Ejemplo n.º 1
0
    def getB(self, pos):

        # vectorized code if input is an Nx3 array
        if type(pos) == ndarray:
            if len(np.shape(
                    pos)) == 2:  # list of positions - use vectorized code
                # vector size
                NN = np.shape(pos)[0]
                # prepare vector inputs
                POSREL = pos - self.position
                ANG = np.ones(NN) * self.angle
                AX = np.tile(self.axis, (NN, 1))
                MAG = np.tile(self.magnetization, (NN, 1))
                DIM = np.ones(NN) * self.dimension
                # compute rotations and field
                ROTATEDPOS = angleAxisRotationV_priv(ANG, -AX, POSREL)
                BB = Bfield_SphereV(MAG, ROTATEDPOS, DIM)
                BCM = angleAxisRotationV_priv(ANG, AX, BB)

                return BCM

        # secure input type and check input format
        p1 = array(pos, dtype=float64, copy=False)
        # relative position between mag and obs
        posRel = p1 - self.position
        # rotate this vector into the CS of the magnet (inverse rotation)
        rotatedPos = angleAxisRotation_priv(self.angle, -self.axis, posRel)  # pylint: disable=invalid-unary-operand-type
        # rotate field vector back
        BCm = angleAxisRotation_priv(
            self.angle, self.axis,
            Bfield_Sphere(self.magnetization, rotatedPos, self.dimension))
        # BCm is the obtained magnetic field in Cm
        # the field is well known in the magnet coordinates.
        return BCm
Ejemplo n.º 2
0
    def getB(self, pos):  # Particular Line current B field calculation. Check RCS for getB() interface
        
        # vectorized code if input is an Nx3 array
        if type(pos) == ndarray:
            if len(shape(pos))==2: # list of positions - use vectorized code
                # vector size
                NN = shape(pos)[0] 
                # prepare vector inputs
                POSREL = pos - self.position
                ANG = ones(NN)*self.angle
                AX = tile(self.axis,(NN,1))
                # compute rotations and field
                ROTATEDPOS = angleAxisRotationV_priv(ANG, -AX, POSREL)
                BB = Bfield_CurrentLineVV(self.vertices,self.current,ROTATEDPOS)
                BCM = angleAxisRotationV_priv(ANG, AX, BB)

                return BCM
        
        # secure input type and check input format
        p1 = array(pos, dtype=float64, copy=False)
        # relative position between mag and obs
        posRel = p1 - self.position
        # rotate this vector into the CS of the magnet (inverse rotation)
        rotatedPos = angleAxisRotation_priv(self.angle, -self.axis, posRel) # pylint: disable=invalid-unary-operand-type
        # rotate field vector back
        BCm = angleAxisRotation_priv(self.angle, self.axis, Bfield_CurrentLineV(self.vertices, self.current,rotatedPos))
        # BCm is the obtained magnetic field in Cm
        # the field is well known in the magnet coordinates.
        return BCm
Ejemplo n.º 3
0
def test_aaRot_priv():
    A = np.array([22, 133, 244])
    AX = np.array([[.1, .2, .3], [3, 4, 5], [-7, -8, -9]])
    V = np.array([[1, 2, 3], [2, 3, 4], [4, 5, 6]])

    sol = np.array([[
        1.,
        2.,
        3.,
    ], [2.57438857, 2.86042187, 3.76702936],
                    [4.77190313, 4.65730779, 5.70424619]])

    assert amax(abs(angleAxisRotationV_priv(A, AX, V) -
                    sol)) < 1e-6, "bad angleAxisRotationV_priv"
Ejemplo n.º 4
0
def Bfield_CircularCurrentLoopV(I0, D, POS):

    R = D / 2  #radius

    N = len(D)  # vector size

    X, Y, Z = POS[:, 0], POS[:, 1], POS[:, 2]

    RR, PHI = sqrt(X**2 + Y**2), arctan2(Y, X)  # cylindrical coordinates

    deltaP = sqrt((RR + R)**2 + Z**2)
    deltaM = sqrt((RR - R)**2 + Z**2)
    kappa = deltaP**2 / deltaM**2
    kappaBar = 1 - kappa

    # allocate solution vector
    field_R = empty([N])

    # avoid discontinuity of Br on z-axis
    maskRR0 = RR == np.zeros([N])
    field_R[maskRR0] = 0
    # R-component computation
    notM = np.invert(maskRR0)
    field_R[notM] = -2 * 1e-4 * (Z[notM] / RR[notM] / deltaM[notM]) * (
        ellipticKV(kappaBar[notM]) - (2 - kappaBar[notM]) /
        (2 - 2 * kappaBar[notM]) * ellipticEV(kappaBar[notM]))

    # Z-component computation
    field_Z = -2 * 1e-4 * (1 / deltaM) * (
        -ellipticKV(kappaBar) + (2 - kappaBar - 4 * (R / deltaM)**2) /
        (2 - 2 * kappaBar) * ellipticEV(kappaBar))

    # transformation to cartesian coordinates
    Bcy = np.array([field_R, np.zeros(N), field_Z]).T
    AX = np.zeros([N, 3])
    AX[:, 2] = 1
    Bkart = angleAxisRotationV_priv(PHI / pi * 180, AX, Bcy)

    return (Bkart.T * I0).T * 1000  # to mT
Ejemplo n.º 5
0
def getBv_magnet(type, MAG, DIM, POSm, POSo, ANG=[], AX=[], ANCH=[], Nphi0=50):
    """
    Calculate the field of magnets using vectorized performance code.

    Parameters
    ----------

    type : string
        source type either 'box', 'cylinder', 'sphere'.

    MAG : Nx3 numpy array float [mT]
        vector of N magnetizations.

    DIM : NxY numpy array float [mm]
        vector of N dimensions for each evaluation. The form of this vector depends
        on the source type. Y=3/2/1 for box/cylinder/sphere

    POSo : Nx3 numpy array float [mm]
        vector of N positions of the observer.
    
    POSm : Nx3 numpy array float [mm]
        vector of N initial source positions. These positions will be adjusted by
        the given rotation parameters.

    ANG=[] : length M list of size N numpy arrays float [deg]
       Angles of M subsequent rotation operations applied to the N-sized POSm and
       the implicit source orientation.
    
    AX=[] : length M list of Nx3 numpy arrays float []
        Axis vectors of M subsequent rotation operations applied to the N-sized
        POSm and the implicit source orientation.
    
    ANCH=[] : length M list of Nx3 numpy arrays float [mm]
        Anchor positions of M subsequent rotations applied ot the N-sized POSm and
        the implicit source orientation.
    
    Nphi0=50 : integer gives number of iterations used when calculating diametral
        magnetized cylindrical magnets.
    """

    N = len(POSo)

    Q = np.zeros([N, 4])
    Q[:, 0] = 1  # init orientation

    Pm = POSm  #initial position

    #apply rotation operations
    for ANGLE, AXIS, ANCHOR in zip(ANG, AX, ANCH):
        Q = QmultV(getRotQuatV(ANGLE, AXIS), Q)
        Pm = angleAxisRotationV_priv(ANGLE, AXIS, Pm - ANCHOR) + ANCHOR

    # transform into CS of source
    POSrel = POSo - Pm  #relative position
    Qc = QconjV(Q)  #orientierung
    POSrot = QrotationV(Qc, POSrel)  #rotation der pos in das CS der Quelle

    # calculate field
    if type == 'box':
        Brot = Bfield_BoxV(MAG, POSrot, DIM)
    elif type == 'cylinder':
        Brot = Bfield_CylinderV(MAG, POSrot, DIM, Nphi0)
    elif type == 'sphere':
        Brot = Bfield_SphereV(MAG, POSrot, DIM)
    else:
        print('Bad type or WIP')
        return 0

    # transform back
    B = QrotationV(Q, Brot)  #rückrotation des feldes

    return B
Ejemplo n.º 6
0
def getBv_moment(type, MOM, POSm, POSo, ANG=[], AX=[], ANCH=[]):
    """
    Calculate the field of magnetic moments using vectorized performance code.

    Parameters
    ----------

    type : string
        source type: 'dipole'

    MOM : Nx3 numpy array float [mT]
        vector of N dipole moments.

    POSo : Nx3 numpy array float [mm]
        vector of N positions of the observer.
    
    POSm : Nx3 numpy array float [mm]
        vector of N initial source positions. These positions will be adjusted by
        the given rotation parameters.

    ANG=[] : length M list of size N numpy arrays float [deg]
       Angles of M subsequent rotation operations applied to the N-sized POSm and
       the implicit source orientation.
    
    AX=[] : length M list of Nx3 numpy arrays float []
        Axis vectors of M subsequent rotation operations applied to the N-sized
        POSm and the implicit source orientation.
    
    ANCH=[] : length M list of Nx3 numpy arrays float [mm]
        Anchor positions of M subsequent rotations applied ot the N-sized POSm and
        the implicit source orientation.
    """

    N = len(POSo)

    Q = np.zeros([N, 4])
    Q[:, 0] = 1  # init orientation

    Pm = POSm  #initial position

    #apply rotation operations
    for ANGLE, AXIS, ANCHOR in zip(ANG, AX, ANCH):
        Q = QmultV(getRotQuatV(ANGLE, AXIS), Q)
        Pm = angleAxisRotationV_priv(ANGLE, AXIS, Pm - ANCHOR) + ANCHOR

    # transform into CS of source
    POSrel = POSo - Pm  #relative position
    Qc = QconjV(Q)  #orientierung
    POSrot = QrotationV(Qc, POSrel)  #rotation der pos in das CS der Quelle

    # calculate field
    if type == 'dipole':
        Brot = Bfield_DipoleV(MOM, POSrot)
    else:
        print('Bad type')
        return 0

    # transform back
    B = QrotationV(Q, Brot)  #rückrotation des feldes

    return B
Ejemplo n.º 7
0
def getBv_current(type, CURR, DIM, POSm, POSo, ANG=[], AX=[], ANCH=[]):
    """
    Calculate the field of currents using vectorized performance code.

    Parameters
    ----------

    type : string
        source type either 'circular' or 'line'

    MAG : Nx3 numpy array float [mT]
        vector of N magnetizations.

    DIM : NxY numpy array float [mm]
        vector of N dimensions for each evaluation. The form of this vector depends
        on the source type. Y=1/3x3 for circular/line.

    POSo : Nx3 numpy array float [mm]
        vector of N positions of the observer.
    
    POSm : Nx3 numpy array float [mm]
        vector of N initial source positions. These positions will be adjusted by
        the given rotation parameters.

    ANG=[] : length M list of size N numpy arrays float [deg]
       Angles of M subsequent rotation operations applied to the N-sized POSm and
       the implicit source orientation.
    
    AX=[] : length M list of Nx3 numpy arrays float []
        Axis vectors of M subsequent rotation operations applied to the N-sized
        POSm and the implicit source orientation.
    
    ANCH=[] : length M list of Nx3 numpy arrays float [mm]
        Anchor positions of M subsequent rotations applied ot the N-sized POSm and
        the implicit source orientation.
    """
    N = len(POSo)

    Q = np.zeros([N, 4])
    Q[:, 0] = 1  # init orientation

    Pm = POSm  #initial position

    #apply rotation operations
    for ANGLE, AXIS, ANCHOR in zip(ANG, AX, ANCH):
        Q = QmultV(getRotQuatV(ANGLE, AXIS), Q)
        Pm = angleAxisRotationV_priv(ANGLE, AXIS, Pm - ANCHOR) + ANCHOR

    # transform into CS of source
    POSrel = POSo - Pm  #relative position
    Qc = QconjV(Q)  #orientierung
    POSrot = QrotationV(Qc, POSrel)  #rotation der pos in das CS der Quelle

    # calculate field
    if type == 'circular':
        Brot = Bfield_CircularCurrentLoopV(CURR, DIM, POSrot)
    elif type == 'line':
        Brot = Bfield_LineSegmentV(POSrot, DIM[:, 0], DIM[:, 1], CURR)
    else:
        print('Bad type')
        return 0

    # transform back
    B = QrotationV(Q, Brot)  #rückrotation des feldes

    return B