def test_getRotQuatV(): ANGS = np.random.rand(5) * 360 AXES = randomAxisV(5) Qs = getRotQuatV(ANGS, AXES) for Q, ang, axe in zip(Qs, ANGS, AXES): assert amax(Q - array(getRotQuat(ang, axe))) < 1e-10, "bad getRotQuatV"
def test_rot_Q_conversion(): X = array([[.1, .2, .3, .4], [.2, .3, .4, .5], [-.33, -.55, .1, .23]]) ang, ax = getAngAxV(X) Y = getRotQuatV(ang, ax) for x, y in zip(X, Y): assert amax(abs(x[0] - y[0])) < 1e-10, "bad rot-Q conversion" assert amax( abs(x[1:] / amax(abs(x[1:])) - y[1:] / amax(abs(y[1:])))) < 1e-10, "bad rot-Q conversion"
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