def _R2deriv(self, R, z, phi=0., t=0.): """ NAME: _Rderiv PURPOSE: evaluate the second radial derivative for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: the second radial derivative HISTORY: 2018-08-04 - Written - Bovy (UofT) """ Raz2 = (R + self.a)**2 + z**2 Raz = numpy.sqrt(Raz2) m = 4. * R * self.a / Raz2 R2ma2mz2o4aR1m = (R**2 - self.a2 - z**2) / 4. / self.a / R / (1. - m) return (2*R**2+self.a2+3*R*self.a+z**2)/R/Raz2*self._Rforce(R,z)\ +2.*self.a/R/Raz*(m*(R**2+self.a2+z**2)/4./(1.-m)/self.a/R**2\ *special.ellipe(m)\ +(R2ma2mz2o4aR1m/(1.-m)*special.ellipe(m) +0.5*R2ma2mz2o4aR1m*(special.ellipe(m)-special.ellipk(m)) +0.5*(special.ellipe(m)/(1.-m)-special.ellipk(m))/m)\ *4*self.a*(self.a2+z**2-R**2)/Raz2**2)
def action_from_oscillation_amplitude(RFStation, dtmax, timestep=0, Np_histogram=None): ''' Returns the relative action for given oscillation amplitude in time, assuming single-harmonic RF system and no intensity effects. Action is normalised to the value at the separatrix, given in units of 1. Optional: RF parameters at a given timestep (default = 0) are used. Optional: Number of points for histogram output ''' omega_rf = RFStation.omega_RF[0, timestep] xx = x2(omega_rf * dtmax) action = np.zeros(len(xx)) indices = np.where(xx != 1.)[0] indices0 = np.where(xx == 1.)[0] action[indices] = (ellipe(xx[indices]) - (1. - xx[indices]) * ellipk(xx[indices])) if indices0: action[indices0] = np.float(ellipe(xx[indices0])) if Np_histogram != None: histogram, bins = np.histogram(action, Np_histogram, (0, 1)) histogram = np.double(histogram) / np.sum(histogram[:]) bin_centres = 0.5 * (bins[0:-1] + bins[1:]) return action, bin_centres, histogram else: return action
def calc_PrimaryRegion(self, X, Z): """Predicts magnitude and direction of primary field in region""" # CALCULATES INDUCING FIELD WITHIN REGION AND RETURNS AT LOCATIONS # Initiate Variables from object I = self.I a1 = self.a1 eps = 1e-6 mu0 = 4 * np.pi * 1e-7 # 1e9*mu0 s = np.abs(X) # Define Radial Distance k = 4 * a1 * s / (Z**2 + (a1 + s)**2) Bpx = mu0 * np.sign(X) * (Z * I / (2 * np.pi * s + eps)) * ( 1 / np.sqrt(Z**2 + (a1 + s)**2)) * (-sp.ellipk(k) + ((a1**2 + Z**2 + s**2) / (Z**2 + (s - a1)**2)) * sp.ellipe(k)) Bpz = mu0 * (I / (2 * np.pi)) * (1 / np.sqrt(Z**2 + (a1 + s)**2)) * ( sp.ellipk(k) + ((a1**2 - Z**2 - s**2) / (Z**2 + (s - a1)**2)) * sp.ellipe(k)) Bpx[(X > -1.025 * a1) & (X < -0.975 * a1) & (Z > -0.025 * a1) & (Z < 0.025 * a1)] = 0. Bpx[(X < 1.025 * a1) & (X > 0.975 * a1) & (Z > -0.025 * a1) & (Z < 0.025 * a1)] = 0. Bpz[(X > -1.025 * a1) & (X < -0.975 * a1) & (Z > -0.025 * a1) & (Z < 0.025 * a1)] = 0. Bpz[(X < 1.025 * a1) & (X > 0.975 * a1) & (Z > -0.025 * a1) & (Z < 0.025 * a1)] = 0. Babs = np.sqrt(Bpx**2 + Bpz**2) return Bpx, Bpz, Babs
def _R2deriv(self,R,z,phi=0.,t=0.): """ NAME: _Rderiv PURPOSE: evaluate the second radial derivative for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: the second radial derivative HISTORY: 2018-08-04 - Written - Bovy (UofT) """ Raz2= (R+self.a)**2+z**2 Raz= nu.sqrt(Raz2) m= 4.*R*self.a/Raz2 R2ma2mz2o4aR1m= (R**2-self.a2-z**2)/4./self.a/R/(1.-m) return (2*R**2+self.a2+3*R*self.a+z**2)/R/Raz2*self._Rforce(R,z)\ +2.*self.a/R/Raz*(m*(R**2+self.a2+z**2)/4./(1.-m)/self.a/R**2\ *special.ellipe(m)\ +(R2ma2mz2o4aR1m/(1.-m)*special.ellipe(m) +0.5*R2ma2mz2o4aR1m*(special.ellipe(m)-special.ellipk(m)) +0.5*(special.ellipe(m)/(1.-m)-special.ellipk(m))/m)\ *4*self.a*(self.a2+z**2-R**2)/Raz2**2)
def Int3(q, r, R): ''' Integral I3. ''' m = 4 * R * r / (q**2 + (r + R)**2) K0 = ellipk(m) # Complete elliptic integral of the first kind K1 = ellipk(1 - m) E0 = ellipe(m) # Complete elliptic integral of the second kind E1 = ellipe(1 - m) beta = np.arcsin(q / np.sqrt(q**2 + (R - r)**2)) K2 = ellipkinc(beta, 1 - m) # Incomplete elliptic integral of the first kind E2 = ellipeinc(beta, 1 - m) # Incomplete elliptic integral of the second kind Z = E2 - E1 * K2 / K1 # Jacobi zeta function lamb = K2 / K1 + 2 * K0 * Z / np.pi # Heuman’s lambda function I3 = -q * np.sqrt(m) * K0 / (2 * np.pi * R * np.sqrt(r * R)) + ( np.heaviside(r - R, 0.5) - np.heaviside(R - r, 0.5)) * lamb / ( 2 * R) + np.heaviside(R - r, 0.5) / R return I3
def action_from_oscillation_amplitude(RFStation, dtmax, timestep = 0, Np_histogram = None): ''' Returns the relative action for given oscillation amplitude in time, assuming single-harmonic RF system and no intensity effects. Action is normalised to the value at the separatrix, given in units of 1. Optional: RF parameters at a given timestep (default = 0) are used. Optional: Number of points for histogram output ''' omega_rf = RFStation.omega_RF[0,timestep] xx = x2(omega_rf*dtmax) action = np.zeros(len(xx)) indices = np.where(xx != 1.)[0] indices0 = np.where(xx == 1.)[0] action[indices] = (ellipe(xx[indices]) - (1. - xx[indices])*ellipk(xx[indices])) if indices0: action[indices0] = np.float(ellipe(xx[indices0])) if Np_histogram != None: histogram, bins = np.histogram(action, Np_histogram, (0,1)) histogram = np.double(histogram)/np.sum(histogram[:]) bin_centres = 0.5*(bins[0:-1] + bins[1:]) return action, bin_centres, histogram else: return action
def calc_G(lamda, mu, alpha, r): ''' Calculates the G transform for a disk of radius alpha at a distance r, on top of a substrate with Lame parameter lambda and shear modulus mu. lamda: Lame parameter of substrate mu: shear modulus of substrate alpha: disk radius, in metres r: array of distances from centre of disk at which to calculate solution. In metres. eg r = np.linspace(0,50*10**3,num=1000) to go to 50km distance. ''' sigma = lamda + 2 * mu nabla = lamda + mu defm = np.zeros_like(r) r_disk = r[r <= alpha] r_postdisk = r[r >= alpha] defm[r <= alpha] = g * (sigma / (np.pi**2 * mu * nabla * alpha) * special.ellipe( (r_disk / alpha)**2)) defm[r >= alpha] = g * (sigma * r_postdisk / (np.pi**2 * mu * nabla * alpha**2)) * ( special.ellipe((alpha / r_postdisk)**2) - (1 - (alpha / r_postdisk)**2) * special.ellipk( (alpha / r_postdisk)**2)) return defm
def findCap(height, eff): coeffInSideBracketsa = (math.pi * xa) / (2 * height) coeffInSideBracketsb = (math.pi * xb) / (2 * height) coeffInSideBracketsc = (math.pi * xc) / (2 * height) coeffa = math.sinh(coeffInSideBracketsa) coeffasquared = math.pow(coeffa, 2) coeffb = math.sinh(coeffInSideBracketsb) coeffbsquared = math.pow(coeffb, 2) coeffc = math.sinh(coeffInSideBracketsc) coeffcsquared = math.pow(coeffc, 2) kp1 = coeffc / coeffb kInsideSqurt = (coeffbsquared - coeffasquared) / (coeffcsquared - coeffasquared) kp2 = math.sqrt(kInsideSqurt) k = kp1 * kp2 ksquared = math.pow(k, 2) kder = math.sqrt(1 - ksquared) K = ellipe(k) Kder = ellipe(kder) Kcoeff = Kder / K C = 2 * relativePermittivityOfFreeSpace * eff * Kcoeff return C
def _A_impl(self, A): points = self.get_points_cart_ref() points = np.array( np.dot(self.rotMatrix, np.array(np.subtract(points, self.center)).T).T) rho = np.sqrt(np.square(points[:, 0]) + np.square(points[:, 1])) r = np.sqrt( np.square(points[:, 0]) + np.square(points[:, 1]) + np.square(points[:, 2])) alpha = np.sqrt(self.r0**2 + np.square(r) - 2 * self.r0 * rho) beta = np.sqrt(self.r0**2 + np.square(r) + 2 * self.r0 * rho) k = np.sqrt(1 - np.divide(np.square(alpha), np.square(beta))) ellipek2 = ellipe(k**2) ellipkk2 = ellipk(k**2) A[:] = -self.Inorm / 2 * np.dot( self.rotMatrixInv, np.array( (2 * self.r0 + np.sqrt(points[:, 0]**2 + points[:, 1]**2) * ellipek2 + (self.r0**2 + points[:, 0]**2 + points[:, 1]**2 + points[:, 2]**2) * (ellipe(k**2) - ellipkk2)) / ((points[:, 0]**2 + points[:, 1]**2) * np.sqrt(self.r0**2 + points[:, 0]**2 + points[:, 1]**2 + 2 * self.r0 * np.sqrt(points[:, 0]**2 + points[:, 1]**2) + points[:, 2]**2)) * np.array([-points[:, 1], points[:, 0], 0])).T)
def calc_PrimaryLoop(self): """Predicts magnitude and direction of primary field in loop center""" # CALCULATES INDUCING FIELD AT RX LOOP CENTER # Initiate Variables I = self.I a1 = self.a1 x = self.x z = self.z eps = 1e-7 mu0 = 4 * np.pi * 1e-7 # 1e9*mu0 s = np.abs(x) # Define Radial Distance k = 4 * a1 * s / (z**2 + (a1 + s)**2) Bpx = mu0 * np.sign(x) * (z * I / (2 * np.pi * s + eps)) * ( 1 / np.sqrt(z**2 + (a1 + s)**2)) * (-sp.ellipk(k) + ((a1**2 + z**2 + s**2) / (z**2 + (s - a1)**2)) * sp.ellipe(k)) Bpz = mu0 * (I / (2 * np.pi)) * (1 / np.sqrt(z**2 + (a1 + s)**2)) * ( sp.ellipk(k) + ((a1**2 - z**2 - s**2) / (z**2 + (s - a1)**2)) * sp.ellipe(k)) self.Bpx = Bpx self.Bpz = Bpz
def f2D(k, k_fermi): """Return the value of the function f2D from Guiliani and Vignale, pg 81.""" y = np.linalg.norm(k) / k_fermi if y <= 1.0: return special.ellipe(y) else: return y * (special.ellipe(1.0 / y) - (1.0 - (1.0 / y**2)) * special.ellipk(1.0 / y))
def cal_cp(Dw, alpha0, Dpw, ri, re, Ep, ve, tol=0.001): """ calculation of the spring constant cp, acc. to ISO 16218 Function 11. Args: tol: tolerance for convergence Dw: diameter of the ball alpha0: initial contact angle Dpw: pitch diameter of the bearing ri: cross-sectional raceway groove radius, inner re: cross-sectional raceway groove radius, outer Ep: modulus of elasticity ve: poisson's ratio Returns: cp: float """ gamma = Dw * cos(alpha0) / Dpw # 内外圈曲率和 rho_i = 2 / Dw * (2 + gamma / (1 - gamma) - Dw / 2 / ri) rho_e = 2 / Dw * (2 - gamma / (1 + gamma) - Dw / 2 / re) # 内外圈曲率差 Fip = (gamma / (1 - gamma) + Dw / 2 / ri) / (2 + gamma / (1 - gamma) - Dw / 2 / ri) Fep = (-gamma / (1 + gamma) + Dw / 2 / re) / (2 - gamma / (1 + gamma) - Dw / 2 / ri) for k in arange(0, 1, 0.001): # 内圈迭代求解 if k == 0: chi = float("inf") else: chi = 1 / k M = 1 - 1 / chi**2 # 第一类和第二类椭圆积分 Ki = ellipk(M) Ei = ellipe(M) Fp = 1 - 2 / (chi**2 - 1) * (Ki / Ei - 1) if abs((Fp - Fip) / Fp) < tol: chi_i = chi break else: pass for k in arange(0, 1, 0.001): # 外圈迭代求解 if k == 0: chi = float("inf") else: chi = 1 / k M = 1 - 1 / chi**2 # 第一类和第二类椭圆积分 Ke = ellipk(M) Ee = ellipe(M) Fp = 1 - 2 / (chi**2 - 1) * (Ke / Ee - 1) if abs((Fp - Fep) / Fp) < tol: chi_e = chi break else: pass return (1.48 * Ep / (1 - ve**2) * ((Ki * (rho_i / chi_i**2 / Ei)**(1 / 3) + Ke * (rho_e / chi_e**2 / Ee)**(1 / 3)))**(-1.5))
def surface_displacement(x, y, transform=0): """ Into surface displacement at the surface for an elliptical contact Parameters ---------- x,y : array-like x and y coordinates of the points of interest transform : int {0,1,2}, optional (0) a flag which defines which axes the result is displayed on. If set to 0 the result is displayed on the 'contact axes' which are aligned with the principal radii of the contact ellipse. If set to 1 or 2 the result is aligned with the axes of the first or second body respectively. Returns ------- displacement : array The into surface displacement at each of the points of interest Notes ----- The pressure distribution is given by: p(x,y)=p0*(1-(x/a)**2-(y/b)**2)**0.5 References ---------- [1] Johnson, K. (1985). Contact Mechanics. Cambridge: Cambridge University Press. doi:10.1017/CBO9781139171731 """ nonlocal l_johnson, m_johnson, n_johnson if l_johnson is None: if b > a: raise ValueError("Change in a>b or b>a between sources, " "sort out") e = (1 - b**2 / a**2)**0.5 l_johnson = np.pi * p0 * b * special.ellipk(e) m_johnson = np.pi * p0 * b / e**2 / a**2 * (special.ellipk(e) - special.ellipe(e)) n_johnson = np.pi * p0 * b / a**2 / e**2 * ( (a**2 / b**2) * special.ellipe(e) - special.ellipk(e)) if transform: x, y = _transform_axes(x, y, [alpha, beta][transform - 1]) out_of_bounds = np.clip((1 - (x / a)**2 - (y / b)**2), 0, float('inf')) == 0 displacement = np.array( (1 - v**2) / modulus / np.pi * (l_johnson - m_johnson * x**2 - n_johnson * y**2)) displacement[out_of_bounds] = float('Nan') return displacement
def EllipticE(): """Return EllipticE.""" if (b == 0): return 0 elif (ksq == 1): return 1 elif (ksq < 1): return ellipe(ksq) else: return ellipe(1. / ksq)
def a_hauptmanmiloh(A): """Calculate the wing lift slope using Hauptman and Miloh's approximation This function calculates the wing lift slope of a finite elliptic wing using the equation a = \left\{\begin{matrix} \left[ \frac{E^2(h)}{\pi A + (4k^3/h) \ln(1/k + h/k)} + \frac{1}{\pi A} \right]^{-1}, & k=\frac{\pi A}{4} \le 1 \\ \left[ \frac{E^2(h)}{4 (k + \sin^{-1}(h)/h)} + \frac{1}{\pi A} \right]^{-1}, & k=\frac{4}{\pi A} \le 1 \end{matrix}\right. which corresponds to the approximation given by Hauptman and Miloh in 1986. Note that a0 does not appear in the equations because they were derived explicitly for a flate plate with a0 = 2*pi. Inputs: A = Aspect ratio of wing (b^2 / Sw) """ if A < (4.0 / np.pi): # Slender wing # Calculate the eccentricity and parameter for the ellipse k = (np.pi * A) / 4.0 h = np.sqrt(1.0 - k**2) # Calculate the perimeter of the ellipse using the complete elliptic # integral of the second kind E = ellipe(h**2) # Calculate the resistance value r1 r1 = (np.pi * A + (4.0 * k**3 / h * np.log((1.0 + h) / k))) / E**2 elif A > (4.0 / np.pi): # High-aspect-ratio wing # Calculate the eccentricity and parameter for the ellipse k = 4.0 / (np.pi * A) h = np.sqrt(1.0 - k**2) # Calculate the perimeter of the ellipse using the complete elliptic # integral of the second kind E = ellipe(h**2) # Calculate the resistance value r1 r1 = 4 * (k + np.arcsin(h) / h) / E**2 else: # Circular wing r1 = 32.0 / (2.0 + np.pi**2) # Calculate the resistance value r2 r2 = np.pi * A # Calculate the wing lift slope using the parallel resistors method return resistance_parallel(r1, r2)
def loop_current(a, I, rho, z): alphasq = a * a + rho * rho + z * z - 2 * a * rho betasq = a * a + rho * rho + z * z + 2 * a * rho beta = sqrt(betasq) ksq = 1. - alphasq / betasq C = mu0 * I / pi Brho = (C * z / (2 * alphasq * rho * beta)) * ( (a * a + rho * rho + z * z) * ellipe(ksq) - alphasq * ellipk(ksq)) Bz = (C / (2 * alphasq * beta)) * ( (a * a - rho * rho - z * z) * ellipe(ksq) + alphasq * ellipk(ksq)) return Brho, Bz
def findC0(xa, xb, xc): xasquared = xa**2 xbsquared = math.pow(xb, 2) xcsquared = math.pow(xc, 2) kp1 = xc / xb kInsideSqurt = (xbsquared - xasquared) / (xcsquared - xasquared) kp2 = math.sqrt(kInsideSqurt) k = kp1 * kp2 ksquared = math.pow(k, 2) kder = math.sqrt(1 - ksquared) K = ellipe(k) Kder = ellipe(kder) C0 = (4 * relativePermittivityOfFreeSpace * Kder) / K return C0
def calc_PrimaryLoop(self): """Predicts magnitude and direction of primary field in loop center""" # CALCULATES INDUCING FIELD AT RX LOOP CENTER # Initiate Variables I = self.I a1 = self.a1 a2 = self.a2 x = self.x z = self.z azm = self.azm eps = 1e-7 mu0 = 4 * np.pi * 1e-7 # 1e9*mu0 s = np.abs(x) # Define Radial Distance k = 4 * a1 * s / (z ** 2 + (a1 + s) ** 2) Bpx = ( mu0 * np.sign(x) * (z * I / (2 * np.pi * s + eps)) * (1 / np.sqrt(z ** 2 + (a1 + s) ** 2)) * ( -sp.ellipk(k) + ((a1 ** 2 + z ** 2 + s ** 2) / (z ** 2 + (s - a1) ** 2)) * sp.ellipe(k) ) ) Bpz = ( mu0 * (I / (2 * np.pi)) * (1 / np.sqrt(z ** 2 + (a1 + s) ** 2)) * ( sp.ellipk(k) + ((a1 ** 2 - z ** 2 - s ** 2) / (z ** 2 + (s - a1) ** 2)) * sp.ellipe(k) ) ) Bpabs = np.sqrt(Bpx ** 2 + Bpz ** 2) Bpn = np.sin(np.deg2rad(azm)) * Bpx + np.cos(np.deg2rad(azm)) * Bpz Area = np.pi * a2 ** 2 self.Bpx = Bpx self.Bpz = Bpz self.Bpabs = Bpabs self.Bpn = Bpn self.Area = Area
def test_comp_ellint_2(): if NumCpp.NO_USE_BOOST and not NumCpp.STL_SPECIAL_FUNCTIONS: return a = np.random.rand(1).item() assert (roundScaler(NumCpp.comp_ellint_2_Scaler(a), NUM_DECIMALS_ROUND) == roundScaler(sp.ellipe(a**2).item(), NUM_DECIMALS_ROUND)) shapeInput = np.random.randint(20, 100, [2, ]) shape = NumCpp.Shape(shapeInput[0].item(), shapeInput[1].item()) aArray = NumCpp.NdArray(shape) a = np.random.rand(shape.rows, shape.cols) aArray.setArray(a) assert np.array_equal(roundArray(NumCpp.comp_ellint_2_Array(aArray), NUM_DECIMALS_ROUND), roundArray(sp.ellipe(np.square(a)), NUM_DECIMALS_ROUND))
def local(self, R): # RCoil=[np.array([1.0,0.0])] r = np.sqrt(R[0]**2 + R[1]**2) z1 = R[2] theta = np.arctan(R[1] / R[0]) Br = 0.0 Bz = 0.0 BrR = 0.0 for n in range(len(self.RCoil)): r0 = self.RCoil[n][0] z0 = self.RCoil[n][1] z = z1 - z0 k = np.sqrt(4 * r * r0 / ((r + r0)**2 + z**2)) IE = sp.ellipe(k) IK = sp.ellipk(k) Br = Br + (1.0 / r) * (z / np.sqrt((r + r0)**2 + z**2)) * \ (-IK + IE * (r0**2 + r**2 + z**2) / ((r0 - r)**2 + z**2)) Bz = Bz + (1.0 / np.sqrt((r + r0)**2 + z**2)) * \ (IK + IE * (r0**2 - r**2 - z**2) / ((r0 - r)**2 + z**2)) if ((r - r0)**2 + z**2 < 0.1**2): Br = 0 Bz = 0 break BV = (mu * self.I0) / (2.0 * r0) / self.nCoil * \ np.array([Br * np.cos(theta), Br * np.sin(theta), Bz]) return BV
def ellippi(n, m): """ Complete elliptic integral of third kind (simplified version). .. FIXME: Incorrect, because of non-standard definitions of elliptic integral in the reference Reference --------- F. LAMARCHE and C. LEROY, Evaluation of the volume of a sphere with a cylinder by elliptic integrals, Computer Phys. Comm. 59 (1990) pg. 365 """ a2 = n k2 = m k2_a2 = k2 + a2 phi = np.arcsin(a2 / k2_a2) Kc = ellipk(k2) Ec = ellipe(k2) Ki = ellipkinc(phi, (1. - k2) ** 1) Ei = ellipeinc(phi, (1. - k2) ** 1) c1 = k2 / k2_a2 c2 = np.sqrt(a2 / (1 + a2) / k2_a2) return c1 * Kc + c2 * ((Kc - Ec) * Ki + Kc * Ei)
def period(self): '''Analytically calculate the period of EKM oscillations.''' # First calculate the limits. xcrit = brentq(lambda x: ellipk(x) - 2 * ellipe(x), 0, 1) phicrit = 3 * (1 - xcrit) / (3 + 2 * xcrit) if self.phiq < phicrit: CKLmin = brentq(lambda CKL: self.chi - self.epsoct - F(CKL), self.tol, self.phiq) else: # Check if flips occur for Omega = Pi or 0 if (np.sign(self.chi - self.epsoct - F(self.tol)) != np.sign(self.chi - self.epsoct - F(self.phiq))): CKLmin = brentq(lambda CKL: self.chi - self.epsoct - F(CKL), self.tol, self.phiq) else: CKLmin = brentq(lambda CKL: self.chi + self.epsoct - F(CKL), self.tol, self.phiq) if self.doesflip(): CKLmax = self.phiq else: CKLmax = brentq(lambda CKL: self.chi + self.epsoct - F(CKL), 0, 1) prefactor = 256 * np.sqrt(10) / (15 * np.pi) / self.epsoct P = quad(lambda CKL: (prefactor * ellipk((3 - 3*CKL)/(3 + 2*CKL)) / (4 - 11*CKL) / np.sqrt(6 + 4*CKL) / np.sqrt(1 - 1/self.epsoct**2 * (F(CKL) - self.chi)**2) / np.sqrt(2* np.fabs(self.phiq - CKL))), CKLmin, CKLmax, epsabs=1e-12, epsrel=1e-12, limit=100) return P[0]
def cnoidalwaves(x, t, dx, a0, a1, g, k): n = len(x) u = zeros(n) h = zeros(n) bed = zeros(n) m = k * k h0 = a0 + a1 * (float(ellipe(m)) / ellipk(m)) c = sqrt((g * a0 * (a0 + a1) * (a0 + (1 - k * k) * a1))) / float(h0) Kc = sqrt(float(3 * a1) / (4 * a0 * (a0 + a1) * (a0 + (1 - k * k) * a1))) for i in range(n): h[i] = a0 + a1 * dnsq(Kc * (x[i] - c * t), m) u[i] = c * (1 - float(h0) / h[i]) h0i = a0 + a1 * dnsq(Kc * (x[0] - dx - c * t), m) u0i = c * (1 - float(h0) / h0i) h1i = a0 + a1 * dnsq(Kc * (x[-1] + dx - c * t), m) u1i = c * (1 - float(h0) / h1i) G = getGfromupy(h, u, bed, u0i, u1i, h0i, h1i, bed[0], bed[-1], dx) return h, u, G, bed
def ring_force(): s = rp - rq a = rp + rq four = -4 * (rp * rq) / s**2 val = (1 / (2 * pi)) * q_q * q_p * (2 / (rp * np.abs(s) * a)) * (s * sp.ellipe(four) + a * \ sp.ellipk(four)) return val
def ellippi(n, m): """ Complete elliptic integral of third kind (simplified version). .. FIXME: Incorrect, because of non-standard definitions of elliptic integral in the reference Reference --------- F. LAMARCHE and C. LEROY, Evaluation of the volume of a sphere with a cylinder by elliptic integrals, Computer Phys. Comm. 59 (1990) pg. 365 """ a2 = n k2 = m k2_a2 = k2 + a2 phi = np.arcsin(a2 / k2_a2) Kc = ellipk(k2) Ec = ellipe(k2) Ki = ellipkinc(phi, (1. - k2)**1) Ei = ellipeinc(phi, (1. - k2)**1) c1 = k2 / k2_a2 c2 = np.sqrt(a2 / (1 + a2) / k2_a2) return c1 * Kc + c2 * ((Kc - Ec) * Ki + Kc * Ei)
def _B_impl(self, B): points = self.get_points_cart_ref() points = np.array( np.dot(self.rotMatrix, np.array(np.subtract(points, self.center)).T).T) rho = np.sqrt(np.square(points[:, 0]) + np.square(points[:, 1])) r = np.sqrt( np.square(points[:, 0]) + np.square(points[:, 1]) + np.square(points[:, 2])) alpha = np.sqrt(self.r0**2 + np.square(r) - 2 * self.r0 * rho) beta = np.sqrt(self.r0**2 + np.square(r) + 2 * self.r0 * rho) k = np.sqrt(1 - np.divide(np.square(alpha), np.square(beta))) ellipek2 = ellipe(k**2) ellipkk2 = ellipk(k**2) gamma = np.square(points[:, 0]) - np.square(points[:, 1]) B[:] = np.dot( self.rotMatrixInv, np.array([ self.Inorm * points[:, 0] * points[:, 2] / (2 * alpha**2 * beta * rho**2) * ((self.r0**2 + r**2) * ellipek2 - alpha**2 * ellipkk2), self.Inorm * points[:, 1] * points[:, 2] / (2 * alpha**2 * beta * rho**2) * ((self.r0**2 + r**2) * ellipek2 - alpha**2 * ellipkk2), self.Inorm / (2 * alpha**2 * beta) * ((self.r0**2 - r**2) * ellipek2 + alpha**2 * ellipkk2) ])).T
def strains_lat(eps_22, eps_33, r0): # computes lateral strains for a 0 deg triax test (vertical bedding planes), # based on strains in 22- and 33-direction # compute initial circumference u0 = 2. * np.pi * r0 # compute main radii of ellipsis, based on the strains r_22 = r0 * (1. + eps_22) r_33 = r0 * (1. + eps_33) # check which radius is larger and assign it to a and the smaller one to b if r_22 >= r_33: a = r_22 b = r_33 else: a = r_33 b = r_22 # compute elliptical circumference of deformed section aux_e = 1. - b**2 / a**2 u_ellipsis = 4. * a * special.ellipe(aux_e) # compute lateral strains, based on the elliptical circumference and return it return u_ellipsis / u0 - 1.
def sinCurve(plotOrNot): nPoints = 120; #The length of the sine curve y = Asin(kx) x in [0,pi/(2k)] #is E(-A^2k^2)/k E is the Complete elliptic integral of the second kind #can be evaluated as scipy.special.ellipe(m) A = 0.0971; k = 4; xr = 0.15 l = scispe.ellipe(-A**2*(k*np.pi/xr)**2)/(k*np.pi/xr)*(4*k) print('sine curve length is', l) xArray = np.linspace(-xr,xr,num=nPoints) yArray = A*(np.sin(k*np.pi/xr*(xArray + xr) - np.pi/2.0) + 1.0) dl = 0.0 max_ddl,min_ddl = 0.0,1.0 for i in range(len(xArray) - 1): ddl = np.sqrt((xArray[i+1] - xArray[i])**2 + (yArray[i+1] - yArray[i])**2) if ddl > max_ddl: max_ddl = ddl if ddl < min_ddl: min_ddl = ddl dl+= ddl print('discrete sine curve length is', dl, 'max segment length is ', max_ddl, 'min segment length is ', min_ddl) if (plotOrNot): plt.plot(xArray, yArray, '-*') plt.ylim([-0.5, 1.5]) plt.xlim([-1, 1]) plt.show() return nPoints, xArray, yArray
def cnoidalwaves(x,t,dx,a0,a1,g,k): n = len(x) u = zeros(n) h = zeros(n) bed = zeros(n) m = k*k h0 = a0 + a1*(float(ellipe(m)) / ellipk(m)) c = sqrt((g*a0*(a0 + a1)*(a0 + (1 - k*k)*a1))) / float(h0) Kc = sqrt(float(3*a1) / (4*a0*(a0 + a1)*(a0 + (1-k*k)*a1))) for i in range(n): h[i] = a0 + a1*dnsq(Kc*(x[i] - c*t),m) u[i] = c *(1 - float(h0)/h[i]) h0i = a0 + a1*dnsq(Kc*(x[0] - dx - c*t),m) u0i = c *(1 - float(h0)/h0i) h1i = a0 + a1*dnsq(Kc*(x[-1] + dx - c*t),m) u1i = c *(1 - float(h0)/h1i) G = getGfromupy(h,u,bed,u0i,u1i,h0i,h1i,bed[0],bed[-1],dx) return h,u,G,bed
def calculateGreen(self, x, xp): if np.allclose(x, xp, rtol=1.0e-13) or math.fabs(xp[0]) < 1.0e-14: raise FB.SingularPoint r = x[0] rp = xp[0] z = x[1] zp = xp[1] mt = (z - zp)**2 + (r + rp)**2 m = 4 * r * rp / mt self.G = 0.0 self.gradG[0] = 0.0 self.gradG[1] = 0.0 mt = math.sqrt(mt) * np.pi kint = scs.ellipk(m) eint = scs.ellipe(m) if np.isnan(kint) or np.isnan(eint): raise Exception('False elliptic integral m = ' + str(m)) self.G = rp * ((2.0 - m) * kint - 2.0 * eint) / (m * mt) self.gradG[0] = r * (2.0 * m - 4.0) * kint self.gradG[0] += r * (m * m - 8.0 * m + 8.0) / (2.0 * (1.0 - m)) * eint self.gradG[0] += rp * m * kint self.gradG[0] -= rp * m * (2.0 - m) / (2.0 * (1.0 - m)) * eint self.gradG[0] /= (math.sqrt(m) * (math.sqrt(r * rp)**3)) self.gradG[0] *= rp / (4.0 * np.pi) self.gradG[1] = (2.0 - m) / (1.0 - m) * eint - 2.0 * kint self.gradG[1] *= math.sqrt(m) * (z - zp) / (2.0 * math.sqrt(r * rp)**3) self.gradG[1] *= rp / (4.0 * np.pi)
def Bvector(self,r): ''' calculate B vector (T/amp) at a point r. convert r to coil frame. then get B then convert b back to lab frame. ''' x,y,z = self.posToCoil(r) R = self.R rho = norm([x,y]) d = np.sqrt( (R+rho)**2 + z**2 ) if d == 0: # No Coil return np.asarray([0,0,0]) d2 = ( (R-rho)**2 + z**2 ) if d2 == 0: # on coil return np.asarray([0,0,0]) k2 = (4*R*rho)/d**2 K = ellipk(k2) E = ellipe(k2) Bc = (1/d)*(K + E*(R**2 - rho**2 - z**2)/d2) if rho == 0: Br=Ba=Bb = 0 else: Br = (1/rho)*(z/d)*(-K + E*(R**2 + rho**2 + z**2)/d2) Ba = Br*x/rho Bb = Br*y/rho B = np.asarray([Ba,Bb,Bc])*self.unit return self.toLab(B)
def evaluate_field_at_point(self, x, y, z): rad = np.sqrt(x**2 + y**2) # If on-axis if rad / self.radius < 1e-10: return 0.0, 0.0, self.__on_axis_field(z) # z relative to position of coil z_rel = z - self.z b_central = self.__central_field() rad_norm = rad / self.radius z_norm = z_rel / self.radius alpha = (1.0 + rad_norm)**2 + z_norm**2 root_alpha_pi = np.sqrt(alpha) * np.pi beta = 4 * rad_norm / alpha int_e = ellipe(beta) int_k = ellipk(beta) gamma = alpha - 4 * rad_norm b_r = b_central * (int_e * ((1.0 + rad_norm**2 + z_norm**2) / gamma) - int_k) / root_alpha_pi * (z_rel / rad) b_z = b_central * (int_e * ( (1.0 - rad_norm**2 - z_norm**2) / gamma) + int_k) / root_alpha_pi return b_r * x / rad, b_r * y / rad, b_z
def loopbrz(Ra, I0, Nturns, R, Z): # Input # Ra [m] Loop radius # I0 [A] Loop current # Nturns Loop number of turns (windings) # R [m] Radial coordinate of the point # Z [m] Axial coordinate of the point # Output # Br, Bz [T] Radial and Axial components of B-field at (R,Z) # # (Note that singularities are not handled here) mu0 = 4.0e-7 * np.pi B0 = mu0 / 2.0 / Ra * I0 * Nturns alfa = np.absolute(R) / Ra beta = Z / Ra gamma = (Z + 1.0e-10) / (R + 1.0e-10) Q = (1 + alfa)**2 + beta**2 ksq = 4.0 * alfa / Q asq = alfa * alfa bsq = beta * beta Qsp = 1.0 / np.pi / np.sqrt(Q) K = special.ellipk(ksq) E = special.ellipe(ksq) Br = gamma * B0 * Qsp * (E * (1 + asq + bsq) / (Q - 4.0 * alfa) - K) Bz = B0 * Qsp * (E * (1 - asq - bsq) / (Q - 4.0 * alfa) + K) return Br, Bz
def siglecoil_fB(I0,N_coil,r0,x,y,z): c0=4e-7; # mu0/pi=4e-7 I0=I0*N_coil; # current, unit: A C=c0*I0; # Set field for single coil rho=(x**2+y**2)**0.5 r=(x**2+y**2+z**2)**0.5 alpha=(r0**2 + r**2 - 2*r0*rho)**0.5 beta=(r0**2 + r**2 + 2*r0*rho)**0.5 gamma=x**2-y**2 k2 = 1 - alpha**2/beta**2 (K,E)=(sp.ellipk(k2),sp.ellipe(k2)) t1=r0**4*(-gamma*(3*z**2+r0**2) + rho**2*(8*x**2-y**2)) t2=r0**2*(rho**4*(5*x**2+y**2) - 2*rho**2*z**2*(2*x**2+y**2) +3*z**4*gamma) t3=r**4*(2*x**4+gamma*(y**2+z**2)) t4=r0**2*( gamma*(r0**2+2*z**2) - rho**2*(3*x**2-2*y**2) ) t5=r**2*( 2*x**4 + gamma*(y**2 + z**2) ) Bxx=C*z/(2*alpha**4*beta**3*rho**4)* ( (t1-t2-t3)* E + (t4+t5)*alpha**2*K) t1=r0**4*(gamma*(3*z**2+r0**2) + rho**2*(8*y**2-x**2)) t2=r0**2*(rho**4*(5*y**2+x**2) - 2*rho**2*z**2*(2*y**2+x**2) -3*z**4*gamma) t3=r**4*(2*y**4-gamma*(x**2+z**2)) t4=r0**2*( -gamma*(r0**2+2*z**2) - rho**2*(3*y**2-2*x**2) ) t5=r**2*( 2*y**4 - gamma*(x**2 + z**2) ) Byy=C*z/(2*alpha**4*beta**3*rho**4)* ( (t1-t2-t3)* E + (t4+t5)*alpha**2*K ) Bzz=C*z/(2*alpha**4*beta**3)* ( (6*r0**2*(rho**2-z**2) -7*r0**4 + r**4 )* E + (r0**2 - r**2)*alpha**2*K ) return (Bxx,Byy,Bzz)
def champB(self,x,z): if abs(x) < 1e-8: x=0 if x>0: sx = 1 x = -x else: sx = -1 z = z-self.zs x2 = x*x z2 = z*z r2 = x2+z2 b1 = self.a2+ r2 b2 = 2*x*self.a b3 = b1+b2 b4 = b1-b2 b5 = -2*b2/b4 b6 = math.sqrt(b3/b4)*self.i rb3 = math.sqrt(b3) b7 = self.a*b3*rb3 b8 = self.a4-self.a2*(x2-2*z2)+z2*(x2+z2) b9 = (self.a2+z2)*b3 e = ellipe(b5) k = ellipk(b5) bz = b6*((self.a2-r2)*e+b3*k)/b7 if x==0: bx = 0.0 Atheta = 0.0 Adx = bz/2 else: bx = -sx*z/x*b6*(b1*e-b3*k)/b7 Atheta = -sx*b6/x*(-b4*e+(self.a2+r2)*k)/(self.a*rb3) Adx = b6/x2*(b8*e-b9*k)/b7 return [bx,bz,Atheta,Adx]
def champB(self, x, z): if abs(x) < 1e-8: x = 0 if x > 0: sx = 1 x = -x else: sx = -1 z = z - self.zs x2 = x * x z2 = z * z r2 = x2 + z2 b1 = self.a2 + r2 b2 = 2 * x * self.a b3 = b1 + b2 b4 = b1 - b2 b5 = -2 * b2 / b4 b6 = math.sqrt(b3 / b4) * self.i rb3 = math.sqrt(b3) b7 = self.a * b3 * rb3 b8 = self.a4 - self.a2 * (x2 - 2 * z2) + z2 * (x2 + z2) b9 = (self.a2 + z2) * b3 e = ellipe(b5) k = ellipk(b5) bz = b6 * ((self.a2 - r2) * e + b3 * k) / b7 if x == 0: bx = 0.0 Atheta = 0.0 Adx = bz / 2 else: bx = -sx * z / x * b6 * (b1 * e - b3 * k) / b7 Atheta = -sx * b6 / x * (-b4 * e + (self.a2 + r2) * k) / (self.a * rb3) Adx = b6 / x2 * (b8 * e - b9 * k) / b7 return [bx, bz, Atheta, Adx]
def s(ξ, ξ1=1e-5, ξ2=1e5): r""" Returns: -------- .. math :: 2/\pi*E(ξ)+(ξ^2-1)*K(ξ) \text{ if } ξ<=1 2/\pi*ξ*E(1/ξ) \text{ if } ξ>1 Asymptotic cases are approximated by the asymptotic expressions. """ def B(x): return ellipe(x ** 2) + (x ** 2 - 1) * ellipk(x ** 2) m1 = ξ < ξ1 m4 = ξ > ξ2 m = ξ < 1 m2 = np.logical_and(m, np.logical_not(m1)) m3 = np.logical_and(np.logical_not(m), np.logical_not(m4)) r = np.zeros_like(ξ) r[m1] = ξ[m1] ** 2 / 2 r[m4] = ξ[m4] r[m2] = 2 / np.pi * B(ξ[m2]) r[m3] = 2 / np.pi * ξ[m3] * ellipe(1 / ξ[m3] ** 2) return r
def greens(R, Z, Rc, Zc): """ Greens function for the toroidal elliptic operator """ ksq = 4.*R*Rc / ( (R + Rc)**2 + (Z - Zc)**2 ) # k**2 k = sqrt(ksq) return sqrt(R*Rc) * ( (2. - ksq)*ellipk(k) - 2.*ellipe(k) ) / (2.*pi*k)
def WaveLengthDepth(k,a0,a1): """ Returns the wavelength and mean depth of a cnoidal wave with parameters k,a0,a1 """ kappa = np.sqrt(3*a1)/(2*np.sqrt(a0*(a0+a1)*(a0+(1-k*k)*a1))) h0 = a0+ a1*special.ellipe(k)/special.ellipk(k) lam = 2.*special.ellipk(k)/kappa return lam,h0
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 action_from_phase_amplitude(x2): ''' Returns the relative action for given oscillation amplitude in time. Action is normalised to the value at the separatrix, given in units of 1. ''' action = np.zeros(len(x2)) indices = np.where(x2 != 1.)[0] indices0 = np.where(x2 == 1.)[0] action[indices] = (ellipe(x2[indices]) - (1. - x2[indices])*ellipk(x2[indices])) if indices0: action[indices0] = np.float(ellipe(x2[indices0])) return action
def G(x, t_cap, f, t): r = 1. + f*math.cos(t) rcap = 1 + x*math.cos(t_cap) zmzcap = f*math.sin(t) - x*math.sin(t_cap) k = 4*r*rcap/((r+rcap)**2 + zmzcap**2) term1 = np.sqrt((r+rcap)**2 + zmzcap**2) term1 = term1*rcap term2 = (1.e0 - (k)*0.5e0)*scsp.ellipk(k) term2 = term2 - scsp.ellipe(k) return term1*term2
def BxForRot(self,xx,yy,zz): x = (xx-self.x0)*np.cos(self.theta) - (zz-self.z0)*np.sin(self.theta) y = yy-self.y0 z = (xx-self.x0)*np.sin(self.theta) + (zz-self.z0)*np.cos(self.theta) rho2 = x**2 + y**2 r2 = x**2 + y**2 + z**2 alpha2 = self.a**2 + r2 - 2*self.a*np.sqrt(rho2) beta2 = self.a**2 + r2 + 2*self.a*np.sqrt(rho2) k2 = 1 - alpha2/beta2 gamma = x**2 - y**2 C = mu0*self.I/np.pi return C*x*z/(2*alpha2*np.sqrt(beta2)*rho2 + epsilon)*\ ((self.a**2+r2)*sp.ellipe(k2)-alpha2*sp.ellipk(k2))*10**4
def _deriv(self, t, y, epsoct, phiq): # Eqs. 11 of Katz (2011) jz, Omega = y CKL = phiq - jz**2 / 2. x = (3 - 3 * CKL) / (3 + 2 * CKL) fj = (15 * np.pi / (128 * np.sqrt(10)) / ellipk(x) * (4 - 11 * CKL) * np.sqrt(6 + 4 * CKL)) fOmega = ((6 * ellipe(x) - 3 * ellipk(x)) / (4 * ellipk(x))) jzdot = -epsoct * fj * np.sin(Omega) Omegadot = jz * fOmega return [jzdot, Omegadot]
def analyticalSolutionSolitary(x,t,a0,a1): """ Returns the cnoidal solution with parameters k,a0,a1 at (x,t) (possibly arrays) """ k = 0 g = 9.81 kappa = np.sqrt(3*a1)/(2*np.sqrt(a0*(a0+a1))) h0 = a0+ a1*special.ellipe(k)/special.ellipk(k) c = np.sqrt(g*a0*(a0+a1)) h = a0+ a1*np.power(np.cosh(kappa*(x-c*t)),-2) u = c*(1-a0/h) return h,u
def ellipse_circumf(major, minor, semi=True): """ Calculate the circumference of an ellipse given the axe lengths. Parameters ---------- major : number Major axis length minor : number Minor axis length semi : Bool, default True Use semi- (True) or full-axes (False) lengths Returns ------- area : number Area of ellipse """ eccen2 = (major**2 - minor**2) / major**2 if semi: return 4. * major * ellipe(eccen2) elif not semi: return 2. * major * ellipe(eccen2)
def _z2deriv(self,R,z,phi=0.,t=0.): """ NAME: _z2deriv PURPOSE: evaluate the second vertical derivative for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t- time OUTPUT: the second vertical derivative HISTORY: 2018-08-04 - Written - Bovy (UofT) """ Raz2= (R+self.a)**2+z**2 m= 4.*R*self.a/Raz2 # Explicitly swapped in zforce here, so the z/z can be cancelled # and z=0 is handled properly return -4.*(3.*z**2/Raz2-1. +4.*((1.+m)/(1.-m)-special.ellipk(m)/special.ellipe(m))\ *self.a*R*z**2/Raz2**2/m)\ *self.a/(1.-m)*((R+self.a)**2+z**2)**-1.5*special.ellipe(m)
def Bz(self,xx,yy,zz): """Return the z component of the magnetic field in the point of space (xx,yy,zz) """ x = xx-self.x0 y = yy-self.y0 z = zz-self.z0 rho2 = x**2 + y**2 r2 = x**2 + y**2 + z**2 alpha2 = self.a**2 + r2 - 2*self.a*np.sqrt(rho2) beta2 = self.a**2 + r2 + 2*self.a*np.sqrt(rho2) k2 = 1 - alpha2/beta2 gamma = x**2 - y**2 C = mu0*self.I/np.pi return C/(2*alpha2*np.sqrt(beta2))*\ ((self.a**2-r2)*sp.ellipe(k2)+alpha2*sp.ellipk(k2))*10**4
def analyticalSolution(x,t,k,a0,a1): """ Returns the cnoidal solution with parameters k,a0,a1 at (x,t) (possibly arrays) """ g = 9.81 kappa = np.sqrt(3*a1)/(2*np.sqrt(a0*(a0+a1)*(a0+(1-k*k)*a1))) h0 = a0+ a1*special.ellipe(k)/special.ellipk(k) c = np.sqrt(g*a0*(a0+a1)*(a0+(1.-k*k)*a1))/h0 sn,cn,dn,ph = special.ellipj(kappa*(x-c*t),k) h = a0+a1*dn**2 u = c*(1-h0/h) return h,u
def B(self,P): a = self.a theta = self.theta x = P[0] - self.x0 y = P[1] - self.y0 r = x*np.cos(theta)+y*np.sin(theta) z = -x*np.sin(theta)+y*np.cos(theta) # On se ramène à des # coordonnées cylindriques par rapport à la spire. Pour la # suite des calculs, voir l'aticle de T.Pré # http://www.udppc.asso.fr/bupdoc/textes/fichierjoint/918/0918D119.zip k= 4.*abs(r)*a/((a+abs(r))**2+z**2) Kk=sp.ellipk(k) Ek=sp.ellipe(k) Br=self.I*(z/r)/np.sqrt((a+abs(r))**2+z**2)*(-Kk+(a**2+r**2+z**2)/((a-abs(r))**2+z**2)*Ek) Bz=(self.I/np.sqrt((a+abs(r))**2+z**2))*(Kk+((a**2-r**2-z**2)/((a-abs(r))**2+z**2))*Ek) return([Br*np.cos(theta)-Bz*np.sin(theta),Br*np.sin(theta)+Bz*np.cos(theta)])
def _vintersect_sphcyl_ellip(rs, rc, b): """ The cases for which evaluating the volume of intersection of a sphere with a cylinder makes use of elliptic integrals. """ rs3 = rs ** 3 bprc = b + rc bmrc = b - rc A = max(rs ** 2, bprc ** 2) B = min(rs ** 2, bprc ** 2) C = bmrc ** 2 AB = A - B AC = A - C BC = B - C k2 = BC / AC s = bprc * bmrc e1 = ellipk(k2) e2 = ellipe(k2) if bmrc == 0: if rs == bprc: vi = - 4. / 3 * AC ** 0.5 * (s + 2. / 3 * AC) elif rs < bprc: vi = 4. / 3 / A ** 0.5 * (e1 * AB * (3 * B - 2 * A) + e2 * A * (2 * A - 4 * B)) / 3 else: vi = 4. / 3 / A ** 0.5 * (e1 * AB * A - e2 * A * (4 * A - 2 * B)) / 3 else: a2 = 1 - B / C e3 = elliptic_pi(a2, k2) if rs == bprc: vi = (4. / 3 * rs3 * np.arctan(2 * (b * rc) ** 0.5 / bmrc) - 4. / 3 * AC ** 0.5 * (s + 2. / 3 * AC)) elif rs < bprc: vi = (4. / 3 / AC ** 0.5 * (e3 * B ** 2 * s / C + e1 * (s * (A - 2. * B) + AB * (3 * B - C - 2 * A) / 3) + e2 * AC * (-s + (2 * A + 2 * C - 4 * B) / 3))) else: vi = 4. / 3 / AC ** 0.5 * (e3 * A ** 2 * s / C - e1 * (A * s - AB * AC / 3.) - e2 * AC * (s + (4. * A - 2 * B - 2 * C) / 3)) return vi
def force_between_windings(self, r1, r2, z, N_m): m = 4*r1*r2/float((r1+r2)**2+z**2); # Argument of the Elliptic Integrals K = special.ellipk(m); # Complete. First kind. E = special.ellipe(m); # Complete. Second kind. # Current in the coil. I1 = self.c.I; # The magnet is treated as an equivalent coil. # I2 is the current in the equivalent coil. I2 = self.m.B_r * self.m.l_m / float( N_m * MU_0); return ( MU_0 * I1 * I2 * z * np.sqrt(m/float(4*r1*r2)) * (K - E*(m/2.0-1)/float(m-1)) );
def heat_capacity(bond_energy, lower_temperature, higher_temperature, step=0.001): """ Calculate the exact heat capacity. Boltzmann constant is set to 1. Formula from McCoy and Wu, 1973, The Two-Dimensional Ising Model. """ # Shorter variable name to ease formula writing. j = bond_energy exact_heat_capacity = [] for t in np.arange(lower_temperature, higher_temperature, step): b = 1 / t k = 2 * np.sinh(2 * b * j) / np.cosh(2 * b * j)**2 kprime = np.sqrt(1 - k**2) c = (b * j / np.tanh(2 * b * j))**2 * (2 / np.pi) * (2 * ellipk(k**2) - 2 * ellipe(k**2) - (1 - kprime) * (np.pi / 2 + kprime * ellipk(k**2))) exact_heat_capacity.append((t, c)) return exact_heat_capacity
def _zforce(self,R,z,phi=0.,t=0.): """ NAME: _zforce PURPOSE: evaluate the vertical force for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: the vertical force HISTORY: 2018-08-04 - Written - Bovy (UofT) """ m= 4.*R*self.a/((R+self.a)**2+z**2) return -4.*z*self.a/(1.-m)*((R+self.a)**2+z**2)**-1.5*special.ellipe(m)
def force_due_to_shell(self, r, z): force = 0; for e1 in [-1, 1]: for e2 in [-1, 1]: m1 = z - 0.5*e1*self.m.l_m - 0.5*e2*self.c.l_c; m2 = ((self.m.r_m - r) / float(m1))**2 + 1; m3 = np.sqrt((self.m.r_m + r)**2 + m1**2); m4 = 4*self.m.r_m*r / float(m3**2); # Different from paper. fs = ( special.ellipk(m4) - 1.0/m2*special.ellipe(m4) + (m1**2 / float(m3**2) - 1) * mpmath.ellippi(m4/float(1-m2), m4)); force += e1*e2*m1*m2*m3*fs; J1 = self.m.B_r; J2 = MU_0*self.c.N_z*self.c.I/float(self.c.l_c); return (J1*J2)/float(2*MU_0) * force;
def _show_currentloop_field(): '''http://www.netdenizen.com/emagnettest/offaxis/?offaxisloop ''' from numpy import sqrt r = numpy.linspace(0.0, 3.0, 51) z = numpy.linspace(-1.0, 1.0, 51) R, Z = numpy.meshgrid(r, z) a = 1.0 V = 230 * sqrt(2.0) rho = 1.535356e-08 II = V/rho mu0 = pi * 4e-7 alpha = R / a beta = Z / a gamma = Z / R Q = (1+alpha)**2 + beta**2 k = sqrt(4*alpha / Q) from scipy.special import ellipk from scipy.special import ellipe Kk = ellipk(k**2) Ek = ellipe(k**2) B0 = mu0*II / (2*a) V = B0 / (pi*sqrt(Q)) \ * (Ek * (1.0 - alpha**2 - beta**2)/(Q - 4*alpha) + Kk) U = B0 * gamma / (pi*sqrt(Q)) \ * (Ek * (1.0 + alpha**2 + beta**2)/(Q - 4*alpha) - Kk) Q = plt.quiver(R, Z, U, V) plt.quiverkey( Q, 0.7, 0.92, 1e4, '$1e4$', labelpos='W', fontproperties={'weight': 'bold'}, color='r' ) plt.show() return
def _Rforce(self,R,z,phi=0.,t=0.): """ NAME: _Rforce PURPOSE: evaluate the radial force for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: the radial force HISTORY: 2018-08-04 - Written - Bovy (UofT) """ m= 4.*R*self.a/((R+self.a)**2+z**2) return -2.*self.a/R/nu.sqrt((R+self.a)**2+z**2)\ *(m*(R**2-self.a2-z**2)/4./(1.-m)/self.a/R*special.ellipe(m) +special.ellipk(m))
def _Rzderiv(self,R,z,phi=0.,t=0.): """ NAME: _Rzderiv PURPOSE: evaluate the mixed R,z derivative for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: d2phi/dR/dz HISTORY: 2018-08-04 - Written - Bovy (UofT) """ Raz2= (R+self.a)**2+z**2 m= 4.*R*self.a/Raz2 return (3.*(R+self.a)/Raz2 -2.*((1.+m)/(1.-m)-special.ellipk(m)/special.ellipe(m))\ *self.a*(self.a2+z**2-R**2)/Raz2**2/m)*self._zforce(R,z)
def create_mesh(axis0=1, axis1=0.5, num_boundary_points=100): # lengths of major and minor axes a = max(axis0, axis1) b = min(axis0, axis1) # Choose the maximum area of a triangle equal to the area of # an equilateral triangle on the boundary. # For circumference of an ellipse, see # http://en.wikipedia.org/wiki/Ellipse#Circumference eccentricity = np.sqrt(1.0 - (b / a) ** 2) length_boundary = float(4 * a * special.ellipe(eccentricity)) a_boundary = length_boundary / num_boundary_points max_area = a_boundary ** 2 * np.sqrt(3) / 4 # generate points on the circle Phi = np.linspace(0, 2 * np.pi, num_boundary_points, endpoint=False) boundary_points = np.column_stack((a * np.cos(Phi), b * np.sin(Phi))) info = meshpy.triangle.MeshInfo() info.set_points(boundary_points) def _round_trip_connect(start, end): result = [] for i in range(start, end): result.append((i, i + 1)) result.append((end, start)) return result info.set_facets(_round_trip_connect(0, len(boundary_points) - 1)) def _needs_refinement(vertices, area): return bool(area > max_area) meshpy_mesh = meshpy.triangle.build(info, refinement_func=_needs_refinement) # append column pts = np.array(meshpy_mesh.points) points = np.c_[pts[:, 0], pts[:, 1], np.zeros(len(pts))] return points, np.array(meshpy_mesh.elements)
def computeMajor(ratio, circum): """ Use the complete elliptic integrals of second kind to figure out what value of major axis corresponds to the circumference, given b/a ratio :math:`circum = 4 a E(k)` where :math:`k = \\sqrt{ 1- b^2/a^2 } = \\sqrt{1 - ratio^2}` therefore, :math:`a = circum/(4E(k))` *Args:* ratio: ratio of semi-minor to semi-major axis of Ellipse, ratio = b/a <= 1 circum: circumference/perimeter of ellipse *Returns:* a: semi-major axis of ellipse """ k = np.sqrt(1- ratio**2) a = circum/(4*scsp.ellipe(k)) return a