def test_QV(): x = array([[1, 2, 3, 4], [2, 3, 4, 5]]) y = array([[4, 3, 2, 1], [5, 4, 3, 2]]) v = array([[1, 2, 3], [2, 3, 4]]) assert (QmultV(x, y) == array([[-12, 6, 24, 12], [-24, 16, 40, 22]])).all(), "bad QmultV" assert (QconjV(x) == array([[1, -2, -3, -4], [2, -3, -4, -5]])).all(), "bad Qconj" assert (QrotationV(x, v) == array([[54, 60, 78], [140, 158, 200]])).all(), "bad Qrotation"
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
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
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