def field(radius, z=0.0, r=0.0, pos=0.0): """Compute axial and radial component for a current loop Based on formulas taken from <http://www.netdenizen.com/emagnettest/offaxis/?offaxisloop>_ Parameters ---------- radius: float Radius of the coil z : float The distance, on axis, from the center of the current loop to the field measurement point. r : float The the radial distance from the axis of the current loop to the field measurement point. pos : float The position of the center of the coil on the z axis Returns ------- Bz, Br : field in units of (Amperes * mu0 /2/radius) """ r = abs(r) z = z - pos alp = r / radius bet = z / radius Q = ((1 + alp) ** 2 + bet ** 2) # work on magnitude to improve performance m = 4 * alp / Q # K(k) is the complete elliptic integral function, of the first kind. # E(k) is the complete elliptic integral function, of the second kind. K = special.ellipkm1(1 - m) E = special.ellipe(m) # Bo is the magnetic field at the center of the coil (AMPERES MU0/2a) # Bz the magnetic field component that is aligned with the coil axis and # Br the magnetic field component that is in a radial direction. Bz = Br = 0.0 if Q != 0.0 and Q - 4 * alp != 0.0 and z != pos: Bz = (E * (1 - alp ** 2 - bet ** 2) / (Q - 4 * alp) + K) / pi / Q ** 0.5 if r > 0.000000 and Q != 0.0 and Q - 4 * alp != 0.0: gam = z / r Br = gam * (E * (1 + alp ** 2 + bet ** 2) / (Q - 4 * alp) - K) / pi / Q ** 0.5 return Bz, Br
def calcQ(k, v): assert v > 0 and v <= 0.5 assert k >= 0 and k < 1 if k > 0: E = ellipe(k) K = ellipkm1(1 - k) k1sq = 1.0 - k**2 return k**2 / (E * k**2 + v * k1sq * (E - K)) else: return 2.0 / np.pi
def calcR(k, v): assert v > 0 and v <= 0.5 assert k >= 0 and k < 1 if k > 0: E = ellipe(k) K = ellipkm1(1 - k) k1sq = 1.0 - k**2 return k**2 / ((k**2 - v) * E + v * k1sq * K) else: return 2.0 / (np.pi * (1 - v))
def calcK3(axisA, axisB, v, beta, omega, tao): """ """ a, b = float(axisA) / 2, float(axisB) / 2 beta, omega = np.radians(beta), np.radians(omega) k = calcK(a, b) E, K = ellipe(k), ellipkm1(1 - k) Q, R = calcQ(k, v), calcR(k, v) term1 = tao * (1 - v) * np.sqrt(np.pi * b / a) term2 = (a**2 * R * np.sin(beta) * np.cos(omega) - b**2 * Q * np.cos(beta) * np.sin(omega)) term3 = ((a**2 * np.sin(beta)**2 + b**2 * np.cos(beta)**2)**0.25 * (a**4 * np.sin(beta)**2 + b**4 * np.cos(beta)**2)**0.25) return term1 * term2 / term3
def _elliptic_integral(self, m): ''' Handle the calculation of the elliptic integral thank scipy special functions. First we have to precise that with the scipy documention definition of ellipk or ellipkm1, the argument of these function are m = k**2. Next the current method will use ellipk when 0<=m<0.5 and 0.5<=ellipkm1<=1 ''' if m<0.: raise ValueError('The argument of the elliptic integral has to be strictly positive.') if m >1.: raise ValueError('The argument of the elliptic integral has to be smaller than one.') if m < 0.99: return ellipk(m) else: return ellipkm1(m)
def _ellipk(self, k): ''' Handle the calculation of the elliptic integral thanks to scipy special functions module. First we have to precise that with the scipy documention definition of ellipk or ellipkm1, the argument of these function are m = k**2. Next the current method will use ellipk or ellipkm1 following the value of m ''' m = k**2. if m < self._ellipk_limit: return ellipk(m) else: return ellipkm1(m)
def MutalInductance(r1, r2, d): # return 0.5 * mu0 * quadrature(_f, 0, 2*nu.pi, args=(r1, r2, d), tol=1e-6, maxiter=100000)[0] if r1 == 0: r1 += 1e-8 if r2 == 0: r2 += 1e-8 squaredK = 4 * r1 * r2 / ((r1 + r2)**2 + d**2) k = nu.sqrt(squaredK) if squaredK != 0 else 0 if k < 0.9: result = mu0 * nu.sqrt(r1 * r2) * ( (2 / k - k) * ellipk(squaredK) - 2 / k * ellipe(squaredK)) else: # k around 1 result = mu0 * nu.sqrt(r1 * r2) * ( (2 / k - k) * ellipkm1(squaredK) - 2 / k * ellipe(squaredK)) if result >= 0: return result else: return 0.5 * mu0 * quadrature( _f, 0, 2 * nu.pi, args=(r1, r2, d), tol=1e-6, maxiter=10000)[0]