From 71f9edaac31ad015a94d00a30755a6f900ed1801 Mon Sep 17 00:00:00 2001 From: SKeeTElor Date: Mon, 7 Apr 2025 13:33:02 -0400 Subject: [PATCH 01/45] First try Cylinder Magnet, using sympy calculate BZ,BZx,BZxx analytically, then convert to numpy function for vectorized calculation. --- mrfmsim/component/magnet.py | 150 ++++++++++++++++++++++++++++++++++++ pyproject.toml | 1 + 2 files changed, 151 insertions(+) diff --git a/mrfmsim/component/magnet.py b/mrfmsim/component/magnet.py index 2b4e060..b699639 100644 --- a/mrfmsim/component/magnet.py +++ b/mrfmsim/component/magnet.py @@ -2,6 +2,9 @@ import numba as nb from dataclasses import dataclass, field from mrfmsim.component import ComponentBase +import sympy as sp +from sympy import elliptic_k, elliptic_pi +from scipy.special import elliprf, ellipk, elliprj, ellipe @dataclass @@ -459,3 +462,150 @@ def _bzxx(dx1, dx2, dy1, dy2, dz1, dz2): * (3.0 * dx2**2 + 2.0 * dy2**2 + 3.0 * dz2**2) / ((dx2**2 + dy2**2 + dz2**2) ** 1.5 * (dx2**2 + dz2**2) ** 2) ) + + + +class CylinderMagnet: + def __init__(self, Radius, Length, magnet_origin, mu0): + self.Radius = Radius + self.Length = Length + self.magnet_origin = magnet_origin + self.mu0 = mu0 + + def ellipiticPi(n, m): + return elliprf(0., 1. - m, 1.) + (n / 3.) * elliprj(0., 1. - m, 1., 1. - n) + + r, Z, R, L = sp.symbols('r Z R L') + + g = (r-R)/(r+R) + + eps1 = Z+L + eps2 = Z-L + + alpha1 = 1/sp.sqrt(eps1**2+(r+R)**2) + alpha2 = 1/sp.sqrt(eps2**2+(r+R)**2) + + k1 = (eps1**2 + (r - R)**2)/(eps1**2 + (r + R)**2) + k2 = (eps2**2 + (r - R)**2)/(eps2**2 + (r + R)**2) + n = 1-g**2 + + + # 定义第三完全椭圆积分 + P21 = -g/(1 - g**2)*(elliptic_pi(n, sp.sqrt(1 - k1)) - elliptic_k(sp.sqrt(1 - k1))) - 1/(1 - g**2)*(g**2*elliptic_pi(n, 1 - k1) - elliptic_k(1 - k1)) + P22 = -g/(1 - g**2)*(elliptic_pi(n, sp.sqrt(1 - k2)) - elliptic_k(sp.sqrt(1 - k2))) - 1/(1 - g**2)*(g**2*elliptic_pi(n, 1 - k2) - elliptic_k(1 - k2)) + + Bz = (P21*alpha1*eps1-P22*eps2*alpha2)*R/(r+R)/sp.pi + + Bzr = sp.diff(Bz,r) + Bzrr = sp.diff(Bzr,r) + + + + # 定义所有需要的特殊函数的映射 + special_functions = { + 'elliptic_k': ellipk, + 'elliptic_e': ellipe, + 'elliptic_pi': ellipiticPi, + 'sqrt': np.sqrt, + 'pi': np.pi + } + + # 使用自定义模块进行转换 + self.Bz_np = sp.lambdify((r, Z, R, L), Bz, modules=[special_functions, 'numpy']) + self.Bzr_np = sp.lambdify((r, Z, R, L), Bzr, modules=[special_functions, 'numpy']) + self.Bzrr_np = sp.lambdify((r, Z, R, L), Bzrr, modules=[special_functions, 'numpy']) + + + def Bz_method(self, x, y, z): + r"""Calculate magnetic field :math:`B_z` [mT]. + + The magnetic field is calculated as + + .. math:: + can be found in the paper:https://doi.org/10.1016/j.jmmm.2018.02.003.(https://www.sciencedirect.com/science/article/pii/S0304885317334662) + + :param float x: x coordinate of sample grid [nm] + :param float y: y coordinate of sample grid [nm] + :param float z: z coordinate of sample grid [nm] + + + Here :math:`(x,y,z)` is the location at which we want to know the field; + :math:`r` is the radius of the magnet; :math:`r**2 = x**2 + y**2`; + :math 'dx = x-x_0' + :math 'dy = y-y_0' + :math 'dz = z-z_0' + distances to the center of the magnet; + :math:`\mu_0 M_s` is the magnetic sphere's saturation + magnetization in mT. + """ + + dr = np.sqrt((x - self.magnet_origin[0])**2+(y - self.magnet_origin[1])**2) + dz = (z - self.magnet_origin[2]) + + pre_term = self.mu0 + + return pre_term * self.Bz_np(dr,dz,self.Radius,self.Length/2) + + + + + def Bzr_method(self, x, y, z): + r"""Calculate magnetic field :math:`B_z` [mT]. + + The magnetic field is calculated as + + .. math: + using sympy directly calculate the derivative of Bz + + :param float x: x coordinate of sample grid [nm] + :param float y: y coordinate of sample grid [nm] + :param float z: z coordinate of sample grid [nm] + + + Here :math:`(x,y,z)` is the location at which we want to know the field; + :math:`r` is the radius of the magnet; :math:`r**2 = x**2 + y**2`; + :math 'dx = x-x_0' + :math 'dy = y-y_0' + :math 'dz = z-z_0' + distances to the center of the magnet; + :math:`\mu_0 M_s` is the magnetic sphere's saturation + magnetization in mT. + """ + + dr = np.sqrt((x - self.magnet_origin[0])**2+(y - self.magnet_origin[1])**2) + dz = (z - self.magnet_origin[2]) + + pre_term = self.mu0 + + return pre_term * self.Bzr_np(dr,dz,self.Radius,self.Length/2) + + + def Bzrr_method(self, x, y, z): + r"""Calculate magnetic field :math:`B_z` [mT]. + + The magnetic field is calculated as + + .. math: + using sympy directly calculate the derivative of Bzr + + :param float x: x coordinate of sample grid [nm] + :param float y: y coordinate of sample grid [nm] + :param float z: z coordinate of sample grid [nm] + + + Here :math:`(x,y,z)` is the location at which we want to know the field; + :math:`r` is the radius of the magnet; :math:`r**2 = x**2 + y**2`; + :math 'dx = x-x_0' + :math 'dy = y-y_0' + :math 'dz = z-z_0' + distances to the center of the magnet; + :math:`\mu_0 M_s` is the magnetic sphere's saturation + magnetization in mT. + """ + + dr = np.sqrt((x - self.magnet_origin[0])**2+(y - self.magnet_origin[1])**2) + dz = (z - self.magnet_origin[2]) + + pre_term = self.mu0 + + return pre_term * self.Bzrr_np(dr,dz,self.Radius,self.Length/2) \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index fa54b2d..7908d6d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,6 +25,7 @@ numpy = ">=1.26.4" mmodel = { git = "https://www.github.com/Marohn-Group/mmodel.git", branch = "develop-0.8.1" } numba = ">=0.60.0" scipy = ">=1.14.1" +sympy = ">=1.13.3" tox = { version = ">=3.25.0", optional = true } tox-conda = { version = ">=0.9.2", optional = true } pytest = { version = ">=7.1.1", optional = true } From 3c996c58553c37d34ad2eae591c6ea282a4432e9 Mon Sep 17 00:00:00 2001 From: SKeeTElor Date: Tue, 8 Apr 2025 21:38:08 -0400 Subject: [PATCH 02/45] All done! --- 1.0.0 | 5 + mrfmsim/component/__init__.py | 1 + mrfmsim/component/magnet.py | 148 +-------------- mrfmsim/component/magnet_cylinder.py | 180 +++++++++++++++++++ tests/test_component/test_megnat_cylinder.py | 70 ++++++++ 5 files changed, 257 insertions(+), 147 deletions(-) create mode 100644 1.0.0 create mode 100644 mrfmsim/component/magnet_cylinder.py create mode 100644 tests/test_component/test_megnat_cylinder.py diff --git a/1.0.0 b/1.0.0 new file mode 100644 index 0000000..a291009 --- /dev/null +++ b/1.0.0 @@ -0,0 +1,5 @@ +Collecting poetry_core + Downloading poetry_core-2.1.2-py3-none-any.whl.metadata (3.5 kB) +Downloading poetry_core-2.1.2-py3-none-any.whl (332 kB) +Installing collected packages: poetry_core +Successfully installed poetry_core-2.1.2 diff --git a/mrfmsim/component/__init__.py b/mrfmsim/component/__init__.py index 34b9c7d..422130e 100644 --- a/mrfmsim/component/__init__.py +++ b/mrfmsim/component/__init__.py @@ -3,3 +3,4 @@ from .cantilever import Cantilever from .grid import Grid from .sample import Sample +from .magnet_cylinder import CylinderMagnet diff --git a/mrfmsim/component/magnet.py b/mrfmsim/component/magnet.py index b699639..4db5f56 100644 --- a/mrfmsim/component/magnet.py +++ b/mrfmsim/component/magnet.py @@ -2,9 +2,7 @@ import numba as nb from dataclasses import dataclass, field from mrfmsim.component import ComponentBase -import sympy as sp -from sympy import elliptic_k, elliptic_pi -from scipy.special import elliprf, ellipk, elliprj, ellipe + @dataclass @@ -465,147 +463,3 @@ def _bzxx(dx1, dx2, dy1, dy2, dz1, dz2): -class CylinderMagnet: - def __init__(self, Radius, Length, magnet_origin, mu0): - self.Radius = Radius - self.Length = Length - self.magnet_origin = magnet_origin - self.mu0 = mu0 - - def ellipiticPi(n, m): - return elliprf(0., 1. - m, 1.) + (n / 3.) * elliprj(0., 1. - m, 1., 1. - n) - - r, Z, R, L = sp.symbols('r Z R L') - - g = (r-R)/(r+R) - - eps1 = Z+L - eps2 = Z-L - - alpha1 = 1/sp.sqrt(eps1**2+(r+R)**2) - alpha2 = 1/sp.sqrt(eps2**2+(r+R)**2) - - k1 = (eps1**2 + (r - R)**2)/(eps1**2 + (r + R)**2) - k2 = (eps2**2 + (r - R)**2)/(eps2**2 + (r + R)**2) - n = 1-g**2 - - - # 定义第三完全椭圆积分 - P21 = -g/(1 - g**2)*(elliptic_pi(n, sp.sqrt(1 - k1)) - elliptic_k(sp.sqrt(1 - k1))) - 1/(1 - g**2)*(g**2*elliptic_pi(n, 1 - k1) - elliptic_k(1 - k1)) - P22 = -g/(1 - g**2)*(elliptic_pi(n, sp.sqrt(1 - k2)) - elliptic_k(sp.sqrt(1 - k2))) - 1/(1 - g**2)*(g**2*elliptic_pi(n, 1 - k2) - elliptic_k(1 - k2)) - - Bz = (P21*alpha1*eps1-P22*eps2*alpha2)*R/(r+R)/sp.pi - - Bzr = sp.diff(Bz,r) - Bzrr = sp.diff(Bzr,r) - - - - # 定义所有需要的特殊函数的映射 - special_functions = { - 'elliptic_k': ellipk, - 'elliptic_e': ellipe, - 'elliptic_pi': ellipiticPi, - 'sqrt': np.sqrt, - 'pi': np.pi - } - - # 使用自定义模块进行转换 - self.Bz_np = sp.lambdify((r, Z, R, L), Bz, modules=[special_functions, 'numpy']) - self.Bzr_np = sp.lambdify((r, Z, R, L), Bzr, modules=[special_functions, 'numpy']) - self.Bzrr_np = sp.lambdify((r, Z, R, L), Bzrr, modules=[special_functions, 'numpy']) - - - def Bz_method(self, x, y, z): - r"""Calculate magnetic field :math:`B_z` [mT]. - - The magnetic field is calculated as - - .. math:: - can be found in the paper:https://doi.org/10.1016/j.jmmm.2018.02.003.(https://www.sciencedirect.com/science/article/pii/S0304885317334662) - - :param float x: x coordinate of sample grid [nm] - :param float y: y coordinate of sample grid [nm] - :param float z: z coordinate of sample grid [nm] - - - Here :math:`(x,y,z)` is the location at which we want to know the field; - :math:`r` is the radius of the magnet; :math:`r**2 = x**2 + y**2`; - :math 'dx = x-x_0' - :math 'dy = y-y_0' - :math 'dz = z-z_0' - distances to the center of the magnet; - :math:`\mu_0 M_s` is the magnetic sphere's saturation - magnetization in mT. - """ - - dr = np.sqrt((x - self.magnet_origin[0])**2+(y - self.magnet_origin[1])**2) - dz = (z - self.magnet_origin[2]) - - pre_term = self.mu0 - - return pre_term * self.Bz_np(dr,dz,self.Radius,self.Length/2) - - - - - def Bzr_method(self, x, y, z): - r"""Calculate magnetic field :math:`B_z` [mT]. - - The magnetic field is calculated as - - .. math: - using sympy directly calculate the derivative of Bz - - :param float x: x coordinate of sample grid [nm] - :param float y: y coordinate of sample grid [nm] - :param float z: z coordinate of sample grid [nm] - - - Here :math:`(x,y,z)` is the location at which we want to know the field; - :math:`r` is the radius of the magnet; :math:`r**2 = x**2 + y**2`; - :math 'dx = x-x_0' - :math 'dy = y-y_0' - :math 'dz = z-z_0' - distances to the center of the magnet; - :math:`\mu_0 M_s` is the magnetic sphere's saturation - magnetization in mT. - """ - - dr = np.sqrt((x - self.magnet_origin[0])**2+(y - self.magnet_origin[1])**2) - dz = (z - self.magnet_origin[2]) - - pre_term = self.mu0 - - return pre_term * self.Bzr_np(dr,dz,self.Radius,self.Length/2) - - - def Bzrr_method(self, x, y, z): - r"""Calculate magnetic field :math:`B_z` [mT]. - - The magnetic field is calculated as - - .. math: - using sympy directly calculate the derivative of Bzr - - :param float x: x coordinate of sample grid [nm] - :param float y: y coordinate of sample grid [nm] - :param float z: z coordinate of sample grid [nm] - - - Here :math:`(x,y,z)` is the location at which we want to know the field; - :math:`r` is the radius of the magnet; :math:`r**2 = x**2 + y**2`; - :math 'dx = x-x_0' - :math 'dy = y-y_0' - :math 'dz = z-z_0' - distances to the center of the magnet; - :math:`\mu_0 M_s` is the magnetic sphere's saturation - magnetization in mT. - """ - - dr = np.sqrt((x - self.magnet_origin[0])**2+(y - self.magnet_origin[1])**2) - dz = (z - self.magnet_origin[2]) - - pre_term = self.mu0 - - return pre_term * self.Bzrr_np(dr,dz,self.Radius,self.Length/2) \ No newline at end of file diff --git a/mrfmsim/component/magnet_cylinder.py b/mrfmsim/component/magnet_cylinder.py new file mode 100644 index 0000000..b49d122 --- /dev/null +++ b/mrfmsim/component/magnet_cylinder.py @@ -0,0 +1,180 @@ +import numpy as np +import sympy as sp +from sympy import elliptic_k, elliptic_pi +from scipy.special import elliprf, ellipk, elliprj, ellipe +from dataclasses import dataclass, field +from mrfmsim.component import ComponentBase + +@dataclass +class CylinderMagnet(ComponentBase): + """Cylinder magnet object with its Bz, Bzx, Bzxx calculations. + + :param float radius: cylinder magnet radius [nm] !!!There would ba a singularity when x^2+y^2=R^2, so set a small difference to R!!! + :param float length: cylinder magnet length [nm] + :param tuple origin: the position of the magnet origin (x, y, z) + :param float mu0_Ms: permeability of free space [H/m] + """ + + magnet_radius: float = field(metadata={"units": "nm","format": ".1f"}) + magnet_length: float = field( metadata={"units": "nm","format": ".1f"}) + magnet_origin: tuple[float, float, float] = field(metadata={"units": "nm","format": ".1f"}) + mu0_Ms: float = field(metadata={"unit": "mT"}) + + def __post_init__(self): + def ellipiticPi(n, m): + return elliprf(0., 1. - m, 1.) + (n / 3.) * elliprj(0., 1. - m, 1., 1. - n) + + r, Z, R, L = sp.symbols('r Z R L') + + g = (r-R)/(r+R) + + eps1 = Z+L + eps2 = Z-L + + alpha1 = 1/sp.sqrt(eps1**2+(r+R)**2) + alpha2 = 1/sp.sqrt(eps2**2+(r+R)**2) + + k1 = (eps1**2 + (r - R)**2)/(eps1**2 + (r + R)**2) + k2 = (eps2**2 + (r - R)**2)/(eps2**2 + (r + R)**2) + n = 1-g**2 + + + # 定义第三完全椭圆积分 + P21 = -g/(1 - g**2)*(elliptic_pi(n, sp.sqrt(1 - k1)) - elliptic_k(sp.sqrt(1 - k1))) - 1/(1 - g**2)*(g**2*elliptic_pi(n, sp.sqrt(1 - k1)) - elliptic_k(sp.sqrt(1 - k1))) + P22 = -g/(1 - g**2)*(elliptic_pi(n, sp.sqrt(1 - k2)) - elliptic_k(sp.sqrt(1 - k2))) - 1/(1 - g**2)*(g**2*elliptic_pi(n, sp.sqrt(1 - k2)) - elliptic_k(sp.sqrt(1 - k2))) + + Bz = (P21*alpha1*eps1-P22*eps2*alpha2)*R/(r+R)/sp.pi + + Bzr = sp.diff(Bz,r) + Bzrr = sp.diff(Bzr,r) + + + + # 定义所有需要的特殊函数的映射 + special_functions = { + 'elliptic_k': ellipk, + 'elliptic_e': ellipe, + 'elliptic_pi': ellipiticPi, + 'sqrt': np.sqrt, + 'pi': np.pi + } + + # 使用自定义模块进行转换 + self.Bz_np = sp.lambdify((r, Z, R, L), Bz, modules=[special_functions, 'numpy']) + self.Bzr_np = sp.lambdify((r, Z, R, L), Bzr, modules=[special_functions, 'numpy']) + self.Bzrr_np = sp.lambdify((r, Z, R, L), Bzrr, modules=[special_functions, 'numpy']) + + + def Bz_method(self, x, y, z): + r"""Calculate magnetic field :math:`B_z` [mT]. + + The magnetic field is calculated as + + .. math:: + can be found in the paper:https://doi.org/10.1016/j.jmmm.2018.02.003.(https://www.sciencedirect.com/science/article/pii/S0304885317334662) + + :param float x: x coordinate of sample grid [nm] + :param float y: y coordinate of sample grid [nm] + :param float z: z coordinate of sample grid [nm] + + + Here :math:`(x,y,z)` is the location at which we want to know the field; + :math:`r` is the radius of the magnet; :math:`r**2 = x**2 + y**2`; + :math 'dx = x-x_0' + :math 'dy = y-y_0' + :math 'dz = z-z_0' + distances to the center of the magnet; + :math:`\mu_0 M_s` is the magnetic sphere's saturation + magnetization in mT. + """ + + dr = np.sqrt((x - self.magnet_origin[0])**2+(y - self.magnet_origin[1])**2) + dz = (z - self.magnet_origin[2]) + + zero_coords = np.argwhere(dr == 0) + + if zero_coords.size > 0: + dr[zero_coords[0][0]][zero_coords[0][1]][zero_coords[0][2]] = np.nan + BZ = self.mu0_Ms * self.Bz_np(r=dr,Z=dz,R=self.magnet_radius,L=self.magnet_length/2) + BZ[zero_coords[0][0]][zero_coords[0][1]][:] = self.mu0_Ms/2*((dz+self.magnet_length/2)/np.sqrt((dz+self.magnet_length/2)**2+(self.magnet_radius)**2)-(dz-self.magnet_length/2)/np.sqrt((dz-self.magnet_length/2)**2+(self.magnet_radius)**2)) + return BZ + + else: + return self.mu0_Ms * self.Bz_np(r=dr,Z=dz,R=self.magnet_radius,L=self.magnet_length/2) + + + + def Bzx_method(self, x, y, z): + r"""Calculate magnetic field :math:`B_z` [mT]. + + The magnetic field is calculated as + + .. math: + using sympy directly calculate the derivative of Bz + + :param float x: x coordinate of sample grid [nm] + :param float y: y coordinate of sample grid [nm] + :param float z: z coordinate of sample grid [nm] + + Here :math:`(x,y,z)` is the location at which we want to know the field; + :math:`r` is the radius of the magnet; :math:`r**2 = x**2 + y**2`; + :math 'dx = x-x_0' + :math 'dy = y-y_0' + :math 'dz = z-z_0' + distances to the center of the magnet; + :math:`\mu_0 M_s` is the magnetic sphere's saturation + magnetization in mT. + """ + + dr = np.sqrt((x - self.magnet_origin[0])**2+(y - self.magnet_origin[1])**2) + dz = (z - self.magnet_origin[2]) + zero_coords = np.argwhere(dr == 0) + + if zero_coords.size > 0: + dr[zero_coords[0][0]][zero_coords[0][1]][zero_coords[0][2]] = np.nan + BZr = self.mu0_Ms * self.Bzr_np(r=dr,Z=dz,R=self.magnet_radius,L=self.magnet_length/2)*(x - self.magnet_origin[0])/dr + BZr[zero_coords[0][0]][zero_coords[0][1]][:] = np.zeros(len(dz)) + return BZr + + else: + return self.mu0_Ms * self.Bzr_np(r=dr,Z=dz,R=self.magnet_radius,L=self.magnet_length/2)*(x - self.magnet_origin[0])/dr + + + def Bzxx_method(self, x, y, z): + r"""Calculate magnetic field :math:`B_z` [mT]. + + The magnetic field is calculated as + + .. math: + using sympy directly calculate the derivative of Bzr + + :param float x: x coordinate of sample grid [nm] + :param float y: y coordinate of sample grid [nm] + :param float z: z coordinate of sample grid [nm] + + + Here :math:`(x,y,z)` is the location at which we want to know the field; + :math:`r` is the radius of the magnet; :math:`r**2 = x**2 + y**2`; + :math 'dx = x-x_0' + :math 'dy = y-y_0' + :math 'dz = z-z_0' + distances to the center of the magnet; + :math:`\mu_0 M_s` is the magnetic sphere's saturation + magnetization in mT. + """ + + dr = np.sqrt((x - self.magnet_origin[0])**2+(y - self.magnet_origin[1])**2) + dz = (z - self.magnet_origin[2]) + + zero_coords = np.argwhere(dr == 0) + + if zero_coords.size > 0: + dr[zero_coords[0][0]][zero_coords[0][1]][zero_coords[0][2]] = np.nan + BZxx = self.mu0_Ms * self.Bzrr_np(r=dr,Z=dz,R=self.magnet_radius,L=self.magnet_length/2)* (x - self.magnet_origin[0])**2/dr**2 - self.mu0_Ms * self.Bzr_np(r=dr,Z=dz,R=self.magnet_radius,L=self.magnet_length/2)*(y-self.magnet_origin[1])**2/dr**3 + BZxx[zero_coords[0][0]][zero_coords[0][1]][:] = np.zeros(len(dz)) + return BZxx + + else: + return self.mu0_Ms * self.Bzrr_np(r=dr,Z=dz,R=self.magnet_radius,L=self.magnet_length/2)* (x - self.magnet_origin[0])**2/dr**2 - self.mu0_Ms * self.Bzr_np(r=dr,Z=dz,R=self.magnet_radius,L=self.magnet_length/2)*(y-self.magnet_origin[1])**2/dr**3 + + \ No newline at end of file diff --git a/tests/test_component/test_megnat_cylinder.py b/tests/test_component/test_megnat_cylinder.py new file mode 100644 index 0000000..348255d --- /dev/null +++ b/tests/test_component/test_megnat_cylinder.py @@ -0,0 +1,70 @@ +import pytest +import numpy as np +from mrfmsim.component import CylinderMagnet + + +class TestCylinderMagnet: + def setup_method(self): + self.magnet = CylinderMagnet(magnet_radius=0.5, magnet_length=10, magnet_origin=[0, 0, 0], mu0_Ms=1) + + def test_Bz_shape(self): + grid = np.ogrid[-1:1:2j, -1:1:5j, -1:1:10j] + Bz = self.magnet.Bz_method(grid[0], grid[1], grid[2]) + assert Bz.shape == (2, 5, 10) + + def test_Bzx_shape(self): + grid = np.ogrid[-1:1:2j, -1:1:5j, -1:1:10j] + Bzx = self.magnet.Bzx_method(grid[0], grid[1], grid[2]) + assert Bzx.shape == (2, 5, 10) + + def test_Bzxx_shape(self): + grid = np.ogrid[-1:1:2j, -1:1:5j, -1:1:10j] + Bzxx = self.magnet.Bzxx_method(grid[0], grid[1], grid[2]) + assert Bzxx.shape == (2, 5, 10) + + def test_Bz_symmetry(self): + Bz1 = self.magnet.Bz_method(1, 2, 6) + Bz2 = self.magnet.Bz_method(-1, 2, 6) + assert np.allclose(Bz1, Bz2) + + + def test_Bzx_symmetry(self): + Bzx1 = self.magnet.Bzx_method(1, 2, 6) + Bzx2 = self.magnet.Bzx_method(-1, 2, 6) + assert np.allclose(Bzx1, -Bzx2) + + def test_Bzxx_symmetry(self): + Bzxx1 = self.magnet.Bzxx_method(1, 2, 6) + Bzxx2 = self.magnet.Bzxx_method(-1, 2, 6) + assert np.allclose(Bzxx1, Bzxx2) + + + def test_Bz_1(self): + Bz = self.magnet.Bz_method(1, 2, 6) + assert np.allclose(Bz, 0.00567438, atol=1e-5) + + def test_Bzx_1(self): + Bzx = self.magnet.Bzx_method(1, 2, 6) + assert np.allclose(Bzx, -0.00376482, atol=1e-5) + + def test_Bzxx_1(self): + Bzxx = self.magnet.Bzxx_method(1, 2, 6) + assert np.allclose(Bzxx, 0.00545423, atol=1e-5) + + def test_Bz_2(self): + Bz = self.magnet.Bz_method(10, 0, 0) + assert np.allclose(Bz, -0.00146935, atol=1e-5) + + def test_Bzx_2(self): + Bzx = self.magnet.Bzx_method(10, 0, 0) + assert np.allclose(Bzx, 0.000319819, atol=1e-5) + + def test_Bzxx_2(self): + Bzxx = self.magnet.Bzxx_method(10, 0, 0) + assert np.allclose(Bzxx,-0.0000913467, atol=1e-5) + + def test_Bzx_when_x_is_0(self): + Bzx = self.magnet.Bzx_method(0, 10, 0) + assert np.allclose(Bzx, 0, atol=1e-10) + + From ee58012192518619b3043d59f7a5420f9699f08d Mon Sep 17 00:00:00 2001 From: SKeeTElor Date: Wed, 9 Apr 2025 13:43:27 -0400 Subject: [PATCH 03/45] Just realize that the defination of the elliptic integral is different from the paper, the sqrt(1-k^2) is actually 1-k^2. Now fix it --- mrfmsim/component/magnet_cylinder.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mrfmsim/component/magnet_cylinder.py b/mrfmsim/component/magnet_cylinder.py index b49d122..957e42e 100644 --- a/mrfmsim/component/magnet_cylinder.py +++ b/mrfmsim/component/magnet_cylinder.py @@ -40,8 +40,8 @@ def ellipiticPi(n, m): # 定义第三完全椭圆积分 - P21 = -g/(1 - g**2)*(elliptic_pi(n, sp.sqrt(1 - k1)) - elliptic_k(sp.sqrt(1 - k1))) - 1/(1 - g**2)*(g**2*elliptic_pi(n, sp.sqrt(1 - k1)) - elliptic_k(sp.sqrt(1 - k1))) - P22 = -g/(1 - g**2)*(elliptic_pi(n, sp.sqrt(1 - k2)) - elliptic_k(sp.sqrt(1 - k2))) - 1/(1 - g**2)*(g**2*elliptic_pi(n, sp.sqrt(1 - k2)) - elliptic_k(sp.sqrt(1 - k2))) + P21 = -g/(1 - g**2)*(elliptic_pi(n, 1 - k1) - elliptic_k(1 - k1)) - 1/(1 - g**2)*(g**2*elliptic_pi(n, 1 - k1) - elliptic_k(1 - k1)) + P22 = -g/(1 - g**2)*(elliptic_pi(n, 1 - k2) - elliptic_k(1 - k2)) - 1/(1 - g**2)*(g**2*elliptic_pi(n, 1 - k2) - elliptic_k(1 - k2)) Bz = (P21*alpha1*eps1-P22*eps2*alpha2)*R/(r+R)/sp.pi @@ -77,6 +77,7 @@ def Bz_method(self, x, y, z): :param float y: y coordinate of sample grid [nm] :param float z: z coordinate of sample grid [nm] + Note that the definition of the elliptic integral is different from the paper. Here :math:`(x,y,z)` is the location at which we want to know the field; :math:`r` is the radius of the magnet; :math:`r**2 = x**2 + y**2`; From 4dfc1ac97dba3e77ceb9ab722fc302134f6423c4 Mon Sep 17 00:00:00 2001 From: SKeeTElor Date: Sun, 13 Apr 2025 23:03:04 -0400 Subject: [PATCH 04/45] Now I manage not to call the number of elliptic function repeatly, accelerate the calcution 4 times faster --- mrfmsim/component/magnet_cylinder.py | 147 ++++++++++++++++++++------- 1 file changed, 108 insertions(+), 39 deletions(-) diff --git a/mrfmsim/component/magnet_cylinder.py b/mrfmsim/component/magnet_cylinder.py index 957e42e..7ab435a 100644 --- a/mrfmsim/component/magnet_cylinder.py +++ b/mrfmsim/component/magnet_cylinder.py @@ -5,26 +5,20 @@ from dataclasses import dataclass, field from mrfmsim.component import ComponentBase + @dataclass -class CylinderMagnet(ComponentBase): - """Cylinder magnet object with its Bz, Bzx, Bzxx calculations. +class CylinderMagnet2(ComponentBase): + Radius: float = field(default=100, metadata={"units": "nm"}) + Length: float = field(default=100, metadata={"units": "nm"}) + magnet_origin: tuple[float, float, float] = field(default=(0, 0, 0), metadata={"units": "nm"}) + mu0_Ms: float = field(default=4*np.pi*1e-7, metadata={"units": "H/m"}) - :param float radius: cylinder magnet radius [nm] !!!There would ba a singularity when x^2+y^2=R^2, so set a small difference to R!!! - :param float length: cylinder magnet length [nm] - :param tuple origin: the position of the magnet origin (x, y, z) - :param float mu0_Ms: permeability of free space [H/m] - """ + def __post_init__(self): - magnet_radius: float = field(metadata={"units": "nm","format": ".1f"}) - magnet_length: float = field( metadata={"units": "nm","format": ".1f"}) - magnet_origin: tuple[float, float, float] = field(metadata={"units": "nm","format": ".1f"}) - mu0_Ms: float = field(metadata={"unit": "mT"}) - def __post_init__(self): - def ellipiticPi(n, m): - return elliprf(0., 1. - m, 1.) + (n / 3.) * elliprj(0., 1. - m, 1., 1. - n) - r, Z, R, L = sp.symbols('r Z R L') + ep11, ep21, ep31 = sp.symbols('ep11 ep21 ep31') + ep12, ep22, ep32 = sp.symbols('ep12 ep22 ep32') g = (r-R)/(r+R) @@ -48,22 +42,45 @@ def ellipiticPi(n, m): Bzr = sp.diff(Bz,r) Bzrr = sp.diff(Bzr,r) + Bz_subs = Bz.subs({ + sp.elliptic_k(1 - k1): ep11, + sp.elliptic_e(1 - k1): ep21, + sp.elliptic_pi(n, 1 - k1): ep31, + sp.elliptic_k(1 - k2): ep12, + sp.elliptic_e(1 - k2): ep22, + sp.elliptic_pi(n, 1 - k2): ep32 + }) + + Bzr_subs = Bzr.subs({ + sp.elliptic_k(1 - k1): ep11, + sp.elliptic_e(1 - k1): ep21, + sp.elliptic_pi(n, 1 - k1): ep31, + sp.elliptic_k(1 - k2): ep12, + sp.elliptic_e(1 - k2): ep22, + sp.elliptic_pi(n, 1 - k2): ep32 + }) + + Bzrr_subs = Bzrr.subs({ + sp.elliptic_k(1 - k1): ep11, + sp.elliptic_e(1 - k1): ep21, + sp.elliptic_pi(n, 1 - k1): ep31, + sp.elliptic_k(1 - k2): ep12, + sp.elliptic_e(1 - k2): ep22, + sp.elliptic_pi(n, 1 - k2): ep32 + }) - - # 定义所有需要的特殊函数的映射 special_functions = { - 'elliptic_k': ellipk, - 'elliptic_e': ellipe, - 'elliptic_pi': ellipiticPi, 'sqrt': np.sqrt, 'pi': np.pi } # 使用自定义模块进行转换 - self.Bz_np = sp.lambdify((r, Z, R, L), Bz, modules=[special_functions, 'numpy']) - self.Bzr_np = sp.lambdify((r, Z, R, L), Bzr, modules=[special_functions, 'numpy']) - self.Bzrr_np = sp.lambdify((r, Z, R, L), Bzrr, modules=[special_functions, 'numpy']) - + self.Bz_np = sp.lambdify((r, Z, R, L, ep11, ep21, ep31, ep12, ep22, ep32), Bz_subs, modules=[special_functions, 'numpy']) + self.Bzr_np = sp.lambdify((r, Z, R, L, ep11, ep21, ep31, ep12, ep22, ep32), Bzr_subs, modules=[special_functions, 'numpy']) + self.Bzrr_np = sp.lambdify((r, Z, R, L, ep11, ep21, ep31, ep12, ep22, ep32), Bzrr_subs,modules=[special_functions, 'numpy']) + + + def Bz_method(self, x, y, z): r"""Calculate magnetic field :math:`B_z` [mT]. @@ -77,8 +94,7 @@ def Bz_method(self, x, y, z): :param float y: y coordinate of sample grid [nm] :param float z: z coordinate of sample grid [nm] - Note that the definition of the elliptic integral is different from the paper. - + Note that the n in the def of elliptic function is different from the def in the papaer. Here :math:`(x,y,z)` is the location at which we want to know the field; :math:`r` is the radius of the magnet; :math:`r**2 = x**2 + y**2`; :math 'dx = x-x_0' @@ -88,21 +104,38 @@ def Bz_method(self, x, y, z): :math:`\mu_0 M_s` is the magnetic sphere's saturation magnetization in mT. """ - + def ellipiticPi(n, m): + return elliprf(0., 1. - m, 1.) + (n / 3.) * elliprj(0., 1. - m, 1., 1. - n) dr = np.sqrt((x - self.magnet_origin[0])**2+(y - self.magnet_origin[1])**2) dz = (z - self.magnet_origin[2]) + L = self.Length/2 + g = (dr - self.Radius) / (dr + self.Radius) + eps1 = z + L + eps2 = z - L + k1 = (eps1**2 + (dr - self.Radius)**2) / (eps1**2 + (dr + self.Radius)**2) + k2 = (eps2**2 + (dr - self.Radius)**2) / (eps2**2 + (dr + self.Radius)**2) + n = 1 - g**2 + + # 然后分别计算: + ep11 = ellipk(1 - k1) + ep21 = ellipe(1 - k1) + ep31 = ellipiticPi(n, 1 - k1) + + ep12 = ellipk(1 - k2) + ep22 = ellipe(1 - k2) + ep32 = ellipiticPi(n, 1 - k2) zero_coords = np.argwhere(dr == 0) if zero_coords.size > 0: dr[zero_coords[0][0]][zero_coords[0][1]][zero_coords[0][2]] = np.nan - BZ = self.mu0_Ms * self.Bz_np(r=dr,Z=dz,R=self.magnet_radius,L=self.magnet_length/2) - BZ[zero_coords[0][0]][zero_coords[0][1]][:] = self.mu0_Ms/2*((dz+self.magnet_length/2)/np.sqrt((dz+self.magnet_length/2)**2+(self.magnet_radius)**2)-(dz-self.magnet_length/2)/np.sqrt((dz-self.magnet_length/2)**2+(self.magnet_radius)**2)) + BZ = self.mu0_Ms * self.Bz_np(r=dr,Z=dz,R=self.Radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32) + BZ[zero_coords[0][0]][zero_coords[0][1]][:] = self.mu0_Ms/2*((dz+self.Length/2)/np.sqrt((dz+self.Length/2)**2+(self.Radius)**2)-(dz-self.Length/2)/np.sqrt((dz-self.Length/2)**2+(self.Radius)**2)) return BZ else: - return self.mu0_Ms * self.Bz_np(r=dr,Z=dz,R=self.magnet_radius,L=self.magnet_length/2) - + return self.mu0_Ms * self.Bz_np(r=dr,Z=dz,R=self.Radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32) + def Bzx_method(self, x, y, z): @@ -126,19 +159,38 @@ def Bzx_method(self, x, y, z): :math:`\mu_0 M_s` is the magnetic sphere's saturation magnetization in mT. """ - + def ellipiticPi(n, m): + return elliprf(0., 1. - m, 1.) + (n / 3.) * elliprj(0., 1. - m, 1., 1. - n) dr = np.sqrt((x - self.magnet_origin[0])**2+(y - self.magnet_origin[1])**2) dz = (z - self.magnet_origin[2]) zero_coords = np.argwhere(dr == 0) + + L = self.Length/2 + g = (dr - self.Radius) / (dr + self.Radius) + eps1 = z + L + eps2 = z - L + k1 = (eps1**2 + (dr - self.Radius)**2) / (eps1**2 + (dr + self.Radius)**2) + k2 = (eps2**2 + (dr - self.Radius)**2) / (eps2**2 + (dr + self.Radius)**2) + n = 1 - g**2 + + # 然后分别计算: + ep11 = ellipk(1 - k1) + ep21 = ellipe(1 - k1) + ep31 = ellipiticPi(n, 1 - k1) + + ep12 = ellipk(1 - k2) + ep22 = ellipe(1 - k2) + ep32 = ellipiticPi(n, 1 - k2) + if zero_coords.size > 0: dr[zero_coords[0][0]][zero_coords[0][1]][zero_coords[0][2]] = np.nan - BZr = self.mu0_Ms * self.Bzr_np(r=dr,Z=dz,R=self.magnet_radius,L=self.magnet_length/2)*(x - self.magnet_origin[0])/dr + BZr = self.mu0_Ms * self.Bzr_np(r=dr,Z=dz,R=self.Radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32)*(x - self.magnet_origin[0])/dr BZr[zero_coords[0][0]][zero_coords[0][1]][:] = np.zeros(len(dz)) return BZr else: - return self.mu0_Ms * self.Bzr_np(r=dr,Z=dz,R=self.magnet_radius,L=self.magnet_length/2)*(x - self.magnet_origin[0])/dr + return self.mu0_Ms * self.Bzr_np(r=dr,Z=dz,R=self.Radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32) *(x - self.magnet_origin[0])/dr def Bzxx_method(self, x, y, z): @@ -163,19 +215,36 @@ def Bzxx_method(self, x, y, z): :math:`\mu_0 M_s` is the magnetic sphere's saturation magnetization in mT. """ - + def ellipiticPi(n, m): + return elliprf(0., 1. - m, 1.) + (n / 3.) * elliprj(0., 1. - m, 1., 1. - n) dr = np.sqrt((x - self.magnet_origin[0])**2+(y - self.magnet_origin[1])**2) dz = (z - self.magnet_origin[2]) zero_coords = np.argwhere(dr == 0) + L = self.Length/2 + g = (dr - self.Radius) / (dr + self.Radius) + eps1 = z + L + eps2 = z - L + k1 = (eps1**2 + (dr - self.Radius)**2) / (eps1**2 + (dr + self.Radius)**2) + k2 = (eps2**2 + (dr - self.Radius)**2) / (eps2**2 + (dr + self.Radius)**2) + n = 1 - g**2 + + # 然后分别计算: + ep11 = ellipk(1 - k1) + ep21 = ellipe(1 - k1) + ep31 = ellipiticPi(n, 1 - k1) + + ep12 = ellipk(1 - k2) + ep22 = ellipe(1 - k2) + ep32 = ellipiticPi(n, 1 - k2) + if zero_coords.size > 0: dr[zero_coords[0][0]][zero_coords[0][1]][zero_coords[0][2]] = np.nan - BZxx = self.mu0_Ms * self.Bzrr_np(r=dr,Z=dz,R=self.magnet_radius,L=self.magnet_length/2)* (x - self.magnet_origin[0])**2/dr**2 - self.mu0_Ms * self.Bzr_np(r=dr,Z=dz,R=self.magnet_radius,L=self.magnet_length/2)*(y-self.magnet_origin[1])**2/dr**3 + BZxx = self.mu0_Ms * self.Bzrr_np(r=dr,Z=dz,R=self.Radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32)* (x - self.magnet_origin[0])**2/dr**2 - self.mu0_Ms * self.Bzr_np(r=dr,Z=dz,R=self.Radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32)*(y-self.magnet_origin[1])**2/dr**3 BZxx[zero_coords[0][0]][zero_coords[0][1]][:] = np.zeros(len(dz)) return BZxx else: - return self.mu0_Ms * self.Bzrr_np(r=dr,Z=dz,R=self.magnet_radius,L=self.magnet_length/2)* (x - self.magnet_origin[0])**2/dr**2 - self.mu0_Ms * self.Bzr_np(r=dr,Z=dz,R=self.magnet_radius,L=self.magnet_length/2)*(y-self.magnet_origin[1])**2/dr**3 - - \ No newline at end of file + return self.mu0_Ms * self.Bzrr_np(r=dr,Z=dz,R=self.Radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32)* (x - self.magnet_origin[0])**2/dr**2 - self.mu0_Ms * self.Bzr_np(r=dr,Z=dz,R=self.Radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32)*(y-self.magnet_origin[1])**2/dr**3 + \ No newline at end of file From 4f9f2d029178dce03aabc87a24c2d4b8f8d4f03b Mon Sep 17 00:00:00 2001 From: SKeeTElor Date: Sun, 13 Apr 2025 23:24:23 -0400 Subject: [PATCH 05/45] 1 --- mrfmsim/component/magnet_cylinder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mrfmsim/component/magnet_cylinder.py b/mrfmsim/component/magnet_cylinder.py index 7ab435a..f576a05 100644 --- a/mrfmsim/component/magnet_cylinder.py +++ b/mrfmsim/component/magnet_cylinder.py @@ -7,7 +7,7 @@ @dataclass -class CylinderMagnet2(ComponentBase): +class CylinderMagnet(ComponentBase): Radius: float = field(default=100, metadata={"units": "nm"}) Length: float = field(default=100, metadata={"units": "nm"}) magnet_origin: tuple[float, float, float] = field(default=(0, 0, 0), metadata={"units": "nm"}) From 830906e4f302bdc09b33b361e4736a02cfad6e45 Mon Sep 17 00:00:00 2001 From: SKeeTElor Date: Mon, 14 Apr 2025 00:03:06 -0400 Subject: [PATCH 06/45] Fix all the bugs in the CylinderMagnet class --- mrfmsim/component/magnet_cylinder.py | 62 +++++++++++-------- ...at_cylinder.py => test_magnet_cylinder.py} | 12 ++-- 2 files changed, 42 insertions(+), 32 deletions(-) rename tests/test_component/{test_megnat_cylinder.py => test_magnet_cylinder.py} (84%) diff --git a/mrfmsim/component/magnet_cylinder.py b/mrfmsim/component/magnet_cylinder.py index f576a05..78896d0 100644 --- a/mrfmsim/component/magnet_cylinder.py +++ b/mrfmsim/component/magnet_cylinder.py @@ -6,12 +6,21 @@ from mrfmsim.component import ComponentBase + @dataclass -class CylinderMagnet(ComponentBase): - Radius: float = field(default=100, metadata={"units": "nm"}) - Length: float = field(default=100, metadata={"units": "nm"}) - magnet_origin: tuple[float, float, float] = field(default=(0, 0, 0), metadata={"units": "nm"}) - mu0_Ms: float = field(default=4*np.pi*1e-7, metadata={"units": "H/m"}) +class CylinderMagnet(ComponentBase): + """Cylinder magnet object with its Bz, Bzx, Bzxx calculations. + + :param float radius: cylinder magnet radius [nm] !!!There would ba a singularity when x^2+y^2=R^2, so set a small difference to R!!! + :param float length: cylinder magnet length [nm] + :param tuple origin: the position of the magnet origin (x, y, z) + :param float mu0_Ms: permeability of free space [H/m] + """ + + magnet_radius: float = field(metadata={"unit": "nm","format": ".1f"}) + magnet_length: float = field( metadata={"unit": "nm","format": ".1f"}) + magnet_origin: tuple[float, float, float] = field(metadata={"unit": "nm","format": ".1f"}) + mu0_Ms: float = field(metadata={"unit": "mT"}) def __post_init__(self): @@ -94,7 +103,7 @@ def Bz_method(self, x, y, z): :param float y: y coordinate of sample grid [nm] :param float z: z coordinate of sample grid [nm] - Note that the n in the def of elliptic function is different from the def in the papaer. + Here :math:`(x,y,z)` is the location at which we want to know the field; :math:`r` is the radius of the magnet; :math:`r**2 = x**2 + y**2`; :math 'dx = x-x_0' @@ -108,12 +117,12 @@ def ellipiticPi(n, m): return elliprf(0., 1. - m, 1.) + (n / 3.) * elliprj(0., 1. - m, 1., 1. - n) dr = np.sqrt((x - self.magnet_origin[0])**2+(y - self.magnet_origin[1])**2) dz = (z - self.magnet_origin[2]) - L = self.Length/2 - g = (dr - self.Radius) / (dr + self.Radius) + L = self.magnet_length/2 + g = (dr - self.magnet_radius) / (dr + self.magnet_radius) eps1 = z + L eps2 = z - L - k1 = (eps1**2 + (dr - self.Radius)**2) / (eps1**2 + (dr + self.Radius)**2) - k2 = (eps2**2 + (dr - self.Radius)**2) / (eps2**2 + (dr + self.Radius)**2) + k1 = (eps1**2 + (dr - self.magnet_radius)**2) / (eps1**2 + (dr + self.magnet_radius)**2) + k2 = (eps2**2 + (dr - self.magnet_radius)**2) / (eps2**2 + (dr + self.magnet_radius)**2) n = 1 - g**2 # 然后分别计算: @@ -129,12 +138,12 @@ def ellipiticPi(n, m): if zero_coords.size > 0: dr[zero_coords[0][0]][zero_coords[0][1]][zero_coords[0][2]] = np.nan - BZ = self.mu0_Ms * self.Bz_np(r=dr,Z=dz,R=self.Radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32) - BZ[zero_coords[0][0]][zero_coords[0][1]][:] = self.mu0_Ms/2*((dz+self.Length/2)/np.sqrt((dz+self.Length/2)**2+(self.Radius)**2)-(dz-self.Length/2)/np.sqrt((dz-self.Length/2)**2+(self.Radius)**2)) + BZ = self.mu0_Ms * self.Bz_np(r=dr,Z=dz,R=self.magnet_radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32) + BZ[zero_coords[0][0]][zero_coords[0][1]][:] = self.mu0_Ms/2*((dz+self.magnet_length/2)/np.sqrt((dz+self.magnet_length/2)**2+(self.magnet_radius)**2)-(dz-self.magnet_length/2)/np.sqrt((dz-self.magnet_length/2)**2+(self.magnet_radius)**2)) return BZ else: - return self.mu0_Ms * self.Bz_np(r=dr,Z=dz,R=self.Radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32) + return self.mu0_Ms * self.Bz_np(r=dr,Z=dz,R=self.magnet_radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32) @@ -165,12 +174,12 @@ def ellipiticPi(n, m): dz = (z - self.magnet_origin[2]) zero_coords = np.argwhere(dr == 0) - L = self.Length/2 - g = (dr - self.Radius) / (dr + self.Radius) + L = self.magnet_length/2 + g = (dr - self.magnet_radius) / (dr + self.magnet_radius) eps1 = z + L eps2 = z - L - k1 = (eps1**2 + (dr - self.Radius)**2) / (eps1**2 + (dr + self.Radius)**2) - k2 = (eps2**2 + (dr - self.Radius)**2) / (eps2**2 + (dr + self.Radius)**2) + k1 = (eps1**2 + (dr - self.magnet_radius)**2) / (eps1**2 + (dr + self.magnet_radius)**2) + k2 = (eps2**2 + (dr - self.magnet_radius)**2) / (eps2**2 + (dr + self.magnet_radius)**2) n = 1 - g**2 # 然后分别计算: @@ -185,12 +194,12 @@ def ellipiticPi(n, m): if zero_coords.size > 0: dr[zero_coords[0][0]][zero_coords[0][1]][zero_coords[0][2]] = np.nan - BZr = self.mu0_Ms * self.Bzr_np(r=dr,Z=dz,R=self.Radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32)*(x - self.magnet_origin[0])/dr + BZr = self.mu0_Ms * self.Bzr_np(r=dr,Z=dz,R=self.magnet_radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32)*(x - self.magnet_origin[0])/dr BZr[zero_coords[0][0]][zero_coords[0][1]][:] = np.zeros(len(dz)) return BZr else: - return self.mu0_Ms * self.Bzr_np(r=dr,Z=dz,R=self.Radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32) *(x - self.magnet_origin[0])/dr + return self.mu0_Ms * self.Bzr_np(r=dr,Z=dz,R=self.magnet_radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32) *(x - self.magnet_origin[0])/dr def Bzxx_method(self, x, y, z): @@ -222,12 +231,12 @@ def ellipiticPi(n, m): zero_coords = np.argwhere(dr == 0) - L = self.Length/2 - g = (dr - self.Radius) / (dr + self.Radius) + L = self.magnet_length/2 + g = (dr - self.magnet_radius) / (dr + self.magnet_radius) eps1 = z + L eps2 = z - L - k1 = (eps1**2 + (dr - self.Radius)**2) / (eps1**2 + (dr + self.Radius)**2) - k2 = (eps2**2 + (dr - self.Radius)**2) / (eps2**2 + (dr + self.Radius)**2) + k1 = (eps1**2 + (dr - self.magnet_radius)**2) / (eps1**2 + (dr + self.magnet_radius)**2) + k2 = (eps2**2 + (dr - self.magnet_radius)**2) / (eps2**2 + (dr + self.magnet_radius)**2) n = 1 - g**2 # 然后分别计算: @@ -241,10 +250,11 @@ def ellipiticPi(n, m): if zero_coords.size > 0: dr[zero_coords[0][0]][zero_coords[0][1]][zero_coords[0][2]] = np.nan - BZxx = self.mu0_Ms * self.Bzrr_np(r=dr,Z=dz,R=self.Radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32)* (x - self.magnet_origin[0])**2/dr**2 - self.mu0_Ms * self.Bzr_np(r=dr,Z=dz,R=self.Radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32)*(y-self.magnet_origin[1])**2/dr**3 + BZxx = self.mu0_Ms * self.Bzrr_np(r=dr,Z=dz,R=self.magnet_radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32)* (x - self.magnet_origin[0])**2/dr**2 - self.mu0_Ms * self.Bzr_np(r=dr,Z=dz,R=self.magnet_radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32)*(y-self.magnet_origin[1])**2/dr**3 BZxx[zero_coords[0][0]][zero_coords[0][1]][:] = np.zeros(len(dz)) return BZxx else: - return self.mu0_Ms * self.Bzrr_np(r=dr,Z=dz,R=self.Radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32)* (x - self.magnet_origin[0])**2/dr**2 - self.mu0_Ms * self.Bzr_np(r=dr,Z=dz,R=self.Radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32)*(y-self.magnet_origin[1])**2/dr**3 - \ No newline at end of file + return self.mu0_Ms * self.Bzrr_np(r=dr,Z=dz,R=self.magnet_radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32)* (x - self.magnet_origin[0])**2/dr**2 - self.mu0_Ms * self.Bzr_np(r=dr,Z=dz,R=self.magnet_radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32)*(y-self.magnet_origin[1])**2/dr**3 + + \ No newline at end of file diff --git a/tests/test_component/test_megnat_cylinder.py b/tests/test_component/test_magnet_cylinder.py similarity index 84% rename from tests/test_component/test_megnat_cylinder.py rename to tests/test_component/test_magnet_cylinder.py index 348255d..1135377 100644 --- a/tests/test_component/test_megnat_cylinder.py +++ b/tests/test_component/test_magnet_cylinder.py @@ -41,27 +41,27 @@ def test_Bzxx_symmetry(self): def test_Bz_1(self): Bz = self.magnet.Bz_method(1, 2, 6) - assert np.allclose(Bz, 0.00567438, atol=1e-5) + assert np.allclose(Bz, 0.00391404, atol=1e-5) def test_Bzx_1(self): Bzx = self.magnet.Bzx_method(1, 2, 6) - assert np.allclose(Bzx, -0.00376482, atol=1e-5) + assert np.allclose(Bzx, -0.00221805, atol=1e-5) def test_Bzxx_1(self): Bzxx = self.magnet.Bzxx_method(1, 2, 6) - assert np.allclose(Bzxx, 0.00545423, atol=1e-5) + assert np.allclose(Bzxx, 0.0031995877, atol=1e-5) def test_Bz_2(self): Bz = self.magnet.Bz_method(10, 0, 0) - assert np.allclose(Bz, -0.00146935, atol=1e-5) + assert np.allclose(Bz,-0.00044788490737216163, atol=1e-5) def test_Bzx_2(self): Bzx = self.magnet.Bzx_method(10, 0, 0) - assert np.allclose(Bzx, 0.000319819, atol=1e-5) + assert np.allclose(Bzx, 0.00010754599, atol=1e-5) def test_Bzxx_2(self): Bzxx = self.magnet.Bzxx_method(10, 0, 0) - assert np.allclose(Bzxx,-0.0000913467, atol=1e-5) + assert np.allclose(Bzxx,-3.22679905171e-05, atol=1e-5) def test_Bzx_when_x_is_0(self): Bzx = self.magnet.Bzx_method(0, 10, 0) From 0e05d2df95fbe6e77501e60c82cd6f07af485bef Mon Sep 17 00:00:00 2001 From: SKeeTElor Date: Mon, 14 Apr 2025 16:09:48 -0400 Subject: [PATCH 07/45] 1. Use Black formatter to format the code 2. add english comments to the code 3. fix the singularity problem when x^2+y^2=0 for Bzxx 4. use sympy. to replace sp. To do: There might be another way to convert the sympy expression to a function: autowarp, need to try out. --- mrfmsim/component/magnet_cylinder.py | 393 +++++++++++++------ tests/test_component/test_magnet_cylinder.py | 20 +- 2 files changed, 293 insertions(+), 120 deletions(-) diff --git a/mrfmsim/component/magnet_cylinder.py b/mrfmsim/component/magnet_cylinder.py index 78896d0..f9fe860 100644 --- a/mrfmsim/component/magnet_cylinder.py +++ b/mrfmsim/component/magnet_cylinder.py @@ -1,95 +1,114 @@ import numpy as np -import sympy as sp +import sympy from sympy import elliptic_k, elliptic_pi from scipy.special import elliprf, ellipk, elliprj, ellipe from dataclasses import dataclass, field from mrfmsim.component import ComponentBase - @dataclass -class CylinderMagnet(ComponentBase): +class CylinderMagnet(ComponentBase): """Cylinder magnet object with its Bz, Bzx, Bzxx calculations. - :param float radius: cylinder magnet radius [nm] !!!There would ba a singularity when x^2+y^2=R^2, so set a small difference to R!!! + :param float radius: cylinder magnet radius [nm] !!!There would ba a singularity when x^2+y^2=R^2, so set a small difference to R!!! Also when x^2+y^2=0, B_zxx would run into a singularity, try to avoid this point. :param float length: cylinder magnet length [nm] :param tuple origin: the position of the magnet origin (x, y, z) :param float mu0_Ms: permeability of free space [H/m] """ - magnet_radius: float = field(metadata={"unit": "nm","format": ".1f"}) - magnet_length: float = field( metadata={"unit": "nm","format": ".1f"}) - magnet_origin: tuple[float, float, float] = field(metadata={"unit": "nm","format": ".1f"}) + magnet_radius: float = field(metadata={"unit": "nm", "format": ".1f"}) + magnet_length: float = field(metadata={"unit": "nm", "format": ".1f"}) + magnet_origin: tuple[float, float, float] = field( + metadata={"unit": "nm", "format": ".1f"} + ) mu0_Ms: float = field(metadata={"unit": "mT"}) def __post_init__(self): + # first use sympy to calculate the Bz, Bzr, Bzrr,the equation if from paper:https://doi.org/10.1016/j.jmmm.2018.02.003.(https://www.sciencedirect.com/science/article/pii/S0304885317334662), + # note that the def of n is different in the paper and the code, so we need to change the def of n in the code - r, Z, R, L = sp.symbols('r Z R L') - ep11, ep21, ep31 = sp.symbols('ep11 ep21 ep31') - ep12, ep22, ep32 = sp.symbols('ep12 ep22 ep32') - - g = (r-R)/(r+R) - - eps1 = Z+L - eps2 = Z-L - - alpha1 = 1/sp.sqrt(eps1**2+(r+R)**2) - alpha2 = 1/sp.sqrt(eps2**2+(r+R)**2) - - k1 = (eps1**2 + (r - R)**2)/(eps1**2 + (r + R)**2) - k2 = (eps2**2 + (r - R)**2)/(eps2**2 + (r + R)**2) - n = 1-g**2 - - - # 定义第三完全椭圆积分 - P21 = -g/(1 - g**2)*(elliptic_pi(n, 1 - k1) - elliptic_k(1 - k1)) - 1/(1 - g**2)*(g**2*elliptic_pi(n, 1 - k1) - elliptic_k(1 - k1)) - P22 = -g/(1 - g**2)*(elliptic_pi(n, 1 - k2) - elliptic_k(1 - k2)) - 1/(1 - g**2)*(g**2*elliptic_pi(n, 1 - k2) - elliptic_k(1 - k2)) - - Bz = (P21*alpha1*eps1-P22*eps2*alpha2)*R/(r+R)/sp.pi - - Bzr = sp.diff(Bz,r) - Bzrr = sp.diff(Bzr,r) - - Bz_subs = Bz.subs({ - sp.elliptic_k(1 - k1): ep11, - sp.elliptic_e(1 - k1): ep21, - sp.elliptic_pi(n, 1 - k1): ep31, - sp.elliptic_k(1 - k2): ep12, - sp.elliptic_e(1 - k2): ep22, - sp.elliptic_pi(n, 1 - k2): ep32 - }) + r, Z, R, L = sympy.symbols("r Z R L") + ep11, ep21, ep31 = sympy.symbols("ep11 ep21 ep31") + ep12, ep22, ep32 = sympy.symbols("ep12 ep22 ep32") - Bzr_subs = Bzr.subs({ - sp.elliptic_k(1 - k1): ep11, - sp.elliptic_e(1 - k1): ep21, - sp.elliptic_pi(n, 1 - k1): ep31, - sp.elliptic_k(1 - k2): ep12, - sp.elliptic_e(1 - k2): ep22, - sp.elliptic_pi(n, 1 - k2): ep32 - }) + g = (r - R) / (r + R) - Bzrr_subs = Bzrr.subs({ - sp.elliptic_k(1 - k1): ep11, - sp.elliptic_e(1 - k1): ep21, - sp.elliptic_pi(n, 1 - k1): ep31, - sp.elliptic_k(1 - k2): ep12, - sp.elliptic_e(1 - k2): ep22, - sp.elliptic_pi(n, 1 - k2): ep32 - }) + eps1 = Z + L + eps2 = Z - L - special_functions = { - 'sqrt': np.sqrt, - 'pi': np.pi - } - - # 使用自定义模块进行转换 - self.Bz_np = sp.lambdify((r, Z, R, L, ep11, ep21, ep31, ep12, ep22, ep32), Bz_subs, modules=[special_functions, 'numpy']) - self.Bzr_np = sp.lambdify((r, Z, R, L, ep11, ep21, ep31, ep12, ep22, ep32), Bzr_subs, modules=[special_functions, 'numpy']) - self.Bzrr_np = sp.lambdify((r, Z, R, L, ep11, ep21, ep31, ep12, ep22, ep32), Bzrr_subs,modules=[special_functions, 'numpy']) + alpha1 = 1 / sympy.sqrt(eps1**2 + (r + R) ** 2) + alpha2 = 1 / sympy.sqrt(eps2**2 + (r + R) ** 2) + k1 = (eps1**2 + (r - R) ** 2) / (eps1**2 + (r + R) ** 2) + k2 = (eps2**2 + (r - R) ** 2) / (eps2**2 + (r + R) ** 2) + n = 1 - g**2 - + P21 = -g / (1 - g**2) * (elliptic_pi(n, 1 - k1) - elliptic_k(1 - k1)) - 1 / ( + 1 - g**2 + ) * (g**2 * elliptic_pi(n, 1 - k1) - elliptic_k(1 - k1)) + P22 = -g / (1 - g**2) * (elliptic_pi(n, 1 - k2) - elliptic_k(1 - k2)) - 1 / ( + 1 - g**2 + ) * (g**2 * elliptic_pi(n, 1 - k2) - elliptic_k(1 - k2)) + + Bz = (P21 * alpha1 * eps1 - P22 * eps2 * alpha2) * R / (r + R) / sympy.pi + Bzr = sympy.diff(Bz, r) + Bzrr = sympy.diff(Bzr, r) + + # use ep11, ep21, ep31, ep12, ep22, ep32 to replace the elliptic_k, elliptic_e, elliptic_pi, to avoid call elliptic_k, elliptic_e, elliptic_pi repeatedly + Bz_subs = Bz.subs( + { + sympy.elliptic_k(1 - k1): ep11, + sympy.elliptic_e(1 - k1): ep21, + sympy.elliptic_pi(n, 1 - k1): ep31, + sympy.elliptic_k(1 - k2): ep12, + sympy.elliptic_e(1 - k2): ep22, + sympy.elliptic_pi(n, 1 - k2): ep32, + } + ) + + Bzr_subs = Bzr.subs( + { + sympy.elliptic_k(1 - k1): ep11, + sympy.elliptic_e(1 - k1): ep21, + sympy.elliptic_pi(n, 1 - k1): ep31, + sympy.elliptic_k(1 - k2): ep12, + sympy.elliptic_e(1 - k2): ep22, + sympy.elliptic_pi(n, 1 - k2): ep32, + } + ) + + Bzrr_subs = Bzrr.subs( + { + sympy.elliptic_k(1 - k1): ep11, + sympy.elliptic_e(1 - k1): ep21, + sympy.elliptic_pi(n, 1 - k1): ep31, + sympy.elliptic_k(1 - k2): ep12, + sympy.elliptic_e(1 - k2): ep22, + sympy.elliptic_pi(n, 1 - k2): ep32, + } + ) + + special_functions = {"sqrt": np.sqrt, "pi": np.pi} + + # use sympy.lambdify to convert the sympy expression to a numpy function + self.Bz_np = sympy.lambdify( + (r, Z, R, L, ep11, ep21, ep31, ep12, ep22, ep32), + Bz_subs, + modules=[special_functions, "numpy"], + ) + self.Bzr_np = sympy.lambdify( + (r, Z, R, L, ep11, ep21, ep31, ep12, ep22, ep32), + Bzr_subs, + modules=[special_functions, "numpy"], + ) + self.Bzrr_np = sympy.lambdify( + (r, Z, R, L, ep11, ep21, ep31, ep12, ep22, ep32), + Bzrr_subs, + modules=[special_functions, "numpy"], + ) + + # use numpy to calculate the Bz, Bzx, Bzxx def Bz_method(self, x, y, z): r"""Calculate magnetic field :math:`B_z` [mT]. @@ -113,20 +132,30 @@ def Bz_method(self, x, y, z): :math:`\mu_0 M_s` is the magnetic sphere's saturation magnetization in mT. """ + def ellipiticPi(n, m): - return elliprf(0., 1. - m, 1.) + (n / 3.) * elliprj(0., 1. - m, 1., 1. - n) - dr = np.sqrt((x - self.magnet_origin[0])**2+(y - self.magnet_origin[1])**2) - dz = (z - self.magnet_origin[2]) - L = self.magnet_length/2 + return elliprf(0.0, 1.0 - m, 1.0) + (n / 3.0) * elliprj( + 0.0, 1.0 - m, 1.0, 1.0 - n + ) + + dr = np.sqrt( + (x - self.magnet_origin[0]) ** 2 + (y - self.magnet_origin[1]) ** 2 + ) + dz = z - self.magnet_origin[2] + L = self.magnet_length / 2 g = (dr - self.magnet_radius) / (dr + self.magnet_radius) eps1 = z + L eps2 = z - L - k1 = (eps1**2 + (dr - self.magnet_radius)**2) / (eps1**2 + (dr + self.magnet_radius)**2) - k2 = (eps2**2 + (dr - self.magnet_radius)**2) / (eps2**2 + (dr + self.magnet_radius)**2) + k1 = (eps1**2 + (dr - self.magnet_radius) ** 2) / ( + eps1**2 + (dr + self.magnet_radius) ** 2 + ) + k2 = (eps2**2 + (dr - self.magnet_radius) ** 2) / ( + eps2**2 + (dr + self.magnet_radius) ** 2 + ) n = 1 - g**2 - # 然后分别计算: - ep11 = ellipk(1 - k1) + # then we calculate the ep11, ep21, ep31, ep12, ep22, ep32, We will precompute the numerical values of these elliptic functions and pass them as inputs to the functions to avoid repeatedly calling the elliptic functions and thus reduce runtime. However, this will increase memory usage. + ep11 = ellipk(1 - k1) ep21 = ellipe(1 - k1) ep31 = ellipiticPi(n, 1 - k1) @@ -138,14 +167,47 @@ def ellipiticPi(n, m): if zero_coords.size > 0: dr[zero_coords[0][0]][zero_coords[0][1]][zero_coords[0][2]] = np.nan - BZ = self.mu0_Ms * self.Bz_np(r=dr,Z=dz,R=self.magnet_radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32) - BZ[zero_coords[0][0]][zero_coords[0][1]][:] = self.mu0_Ms/2*((dz+self.magnet_length/2)/np.sqrt((dz+self.magnet_length/2)**2+(self.magnet_radius)**2)-(dz-self.magnet_length/2)/np.sqrt((dz-self.magnet_length/2)**2+(self.magnet_radius)**2)) - return BZ + BZ = self.mu0_Ms * self.Bz_np( + r=dr, + Z=dz, + R=self.magnet_radius, + L=L, + ep11=ep11, + ep21=ep21, + ep31=ep31, + ep12=ep12, + ep22=ep22, + ep32=ep32, + ) + BZ[zero_coords[0][0]][zero_coords[0][1]][:] = ( + self.mu0_Ms + / 2 + * ( + (dz + self.magnet_length / 2) + / np.sqrt( + (dz + self.magnet_length / 2) ** 2 + (self.magnet_radius) ** 2 + ) + - (dz - self.magnet_length / 2) + / np.sqrt( + (dz - self.magnet_length / 2) ** 2 + (self.magnet_radius) ** 2 + ) + ) + )#Along the Z-axis, B_z reduces to an algebraic function. Since this point is a singularity in the original expression, we need to manually replace B_z with its corresponding algebraic form. + return BZ else: - return self.mu0_Ms * self.Bz_np(r=dr,Z=dz,R=self.magnet_radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32) - - + return self.mu0_Ms * self.Bz_np( + r=dr, + Z=dz, + R=self.magnet_radius, + L=L, + ep11=ep11, + ep21=ep21, + ep31=ep31, + ep12=ep12, + ep22=ep22, + ep32=ep32, + ) def Bzx_method(self, x, y, z): r"""Calculate magnetic field :math:`B_z` [mT]. @@ -168,22 +230,32 @@ def Bzx_method(self, x, y, z): :math:`\mu_0 M_s` is the magnetic sphere's saturation magnetization in mT. """ + def ellipiticPi(n, m): - return elliprf(0., 1. - m, 1.) + (n / 3.) * elliprj(0., 1. - m, 1., 1. - n) - dr = np.sqrt((x - self.magnet_origin[0])**2+(y - self.magnet_origin[1])**2) - dz = (z - self.magnet_origin[2]) + return elliprf(0.0, 1.0 - m, 1.0) + (n / 3.0) * elliprj( + 0.0, 1.0 - m, 1.0, 1.0 - n + ) + + dr = np.sqrt( + (x - self.magnet_origin[0]) ** 2 + (y - self.magnet_origin[1]) ** 2 + ) + dz = z - self.magnet_origin[2] zero_coords = np.argwhere(dr == 0) - L = self.magnet_length/2 + L = self.magnet_length / 2 g = (dr - self.magnet_radius) / (dr + self.magnet_radius) eps1 = z + L eps2 = z - L - k1 = (eps1**2 + (dr - self.magnet_radius)**2) / (eps1**2 + (dr + self.magnet_radius)**2) - k2 = (eps2**2 + (dr - self.magnet_radius)**2) / (eps2**2 + (dr + self.magnet_radius)**2) + k1 = (eps1**2 + (dr - self.magnet_radius) ** 2) / ( + eps1**2 + (dr + self.magnet_radius) ** 2 + ) + k2 = (eps2**2 + (dr - self.magnet_radius) ** 2) / ( + eps2**2 + (dr + self.magnet_radius) ** 2 + ) n = 1 - g**2 - # 然后分别计算: - ep11 = ellipk(1 - k1) + # then we calculate the ep11, ep21, ep31, ep12, ep22, ep32, We will precompute the numerical values of these elliptic functions and pass them as inputs to the functions to avoid repeatedly calling the elliptic functions and thus reduce runtime. However, this will increase memory usage. + ep11 = ellipk(1 - k1) ep21 = ellipe(1 - k1) ep31 = ellipiticPi(n, 1 - k1) @@ -191,17 +263,47 @@ def ellipiticPi(n, m): ep22 = ellipe(1 - k2) ep32 = ellipiticPi(n, 1 - k2) - if zero_coords.size > 0: dr[zero_coords[0][0]][zero_coords[0][1]][zero_coords[0][2]] = np.nan - BZr = self.mu0_Ms * self.Bzr_np(r=dr,Z=dz,R=self.magnet_radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32)*(x - self.magnet_origin[0])/dr - BZr[zero_coords[0][0]][zero_coords[0][1]][:] = np.zeros(len(dz)) - return BZr + BZr = ( + self.mu0_Ms + * self.Bzr_np( + r=dr, + Z=dz, + R=self.magnet_radius, + L=L, + ep11=ep11, + ep21=ep21, + ep31=ep31, + ep12=ep12, + ep22=ep22, + ep32=ep32, + ) + * (x - self.magnet_origin[0]) + / dr + ) + BZr[zero_coords[0][0]][zero_coords[0][1]][:] = np.zeros(len(dz)) #Along the Z-axis, B_zr would be 0 due to the symmetry + return BZr else: - return self.mu0_Ms * self.Bzr_np(r=dr,Z=dz,R=self.magnet_radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32) *(x - self.magnet_origin[0])/dr + return ( + self.mu0_Ms + * self.Bzr_np( + r=dr, + Z=dz, + R=self.magnet_radius, + L=L, + ep11=ep11, + ep21=ep21, + ep31=ep31, + ep12=ep12, + ep22=ep22, + ep32=ep32, + ) + * (x - self.magnet_origin[0]) + / dr + ) - def Bzxx_method(self, x, y, z): r"""Calculate magnetic field :math:`B_z` [mT]. @@ -224,23 +326,33 @@ def Bzxx_method(self, x, y, z): :math:`\mu_0 M_s` is the magnetic sphere's saturation magnetization in mT. """ + def ellipiticPi(n, m): - return elliprf(0., 1. - m, 1.) + (n / 3.) * elliprj(0., 1. - m, 1., 1. - n) - dr = np.sqrt((x - self.magnet_origin[0])**2+(y - self.magnet_origin[1])**2) - dz = (z - self.magnet_origin[2]) + return elliprf(0.0, 1.0 - m, 1.0) + (n / 3.0) * elliprj( + 0.0, 1.0 - m, 1.0, 1.0 - n + ) + + dr = np.sqrt( + (x - self.magnet_origin[0]) ** 2 + (y - self.magnet_origin[1]) ** 2 + ) + dz = z - self.magnet_origin[2] zero_coords = np.argwhere(dr == 0) - L = self.magnet_length/2 + L = self.magnet_length / 2 g = (dr - self.magnet_radius) / (dr + self.magnet_radius) eps1 = z + L eps2 = z - L - k1 = (eps1**2 + (dr - self.magnet_radius)**2) / (eps1**2 + (dr + self.magnet_radius)**2) - k2 = (eps2**2 + (dr - self.magnet_radius)**2) / (eps2**2 + (dr + self.magnet_radius)**2) + k1 = (eps1**2 + (dr - self.magnet_radius) ** 2) / ( + eps1**2 + (dr + self.magnet_radius) ** 2 + ) + k2 = (eps2**2 + (dr - self.magnet_radius) ** 2) / ( + eps2**2 + (dr + self.magnet_radius) ** 2 + ) n = 1 - g**2 - # 然后分别计算: - ep11 = ellipk(1 - k1) + # then we calculate the ep11, ep21, ep31, ep12, ep22, ep32, We will precompute the numerical values of these elliptic functions and pass them as inputs to the functions to avoid repeatedly calling the elliptic functions and thus reduce runtime. However, this will increase memory usage. + ep11 = ellipk(1 - k1) ep21 = ellipe(1 - k1) ep31 = ellipiticPi(n, 1 - k1) @@ -249,12 +361,71 @@ def ellipiticPi(n, m): ep32 = ellipiticPi(n, 1 - k2) if zero_coords.size > 0: - dr[zero_coords[0][0]][zero_coords[0][1]][zero_coords[0][2]] = np.nan - BZxx = self.mu0_Ms * self.Bzrr_np(r=dr,Z=dz,R=self.magnet_radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32)* (x - self.magnet_origin[0])**2/dr**2 - self.mu0_Ms * self.Bzr_np(r=dr,Z=dz,R=self.magnet_radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32)*(y-self.magnet_origin[1])**2/dr**3 - BZxx[zero_coords[0][0]][zero_coords[0][1]][:] = np.zeros(len(dz)) - return BZxx - - else: - return self.mu0_Ms * self.Bzrr_np(r=dr,Z=dz,R=self.magnet_radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32)* (x - self.magnet_origin[0])**2/dr**2 - self.mu0_Ms * self.Bzr_np(r=dr,Z=dz,R=self.magnet_radius,L=L,ep11=ep11, ep21=ep21, ep31=ep31, ep12=ep12, ep22=ep22, ep32=ep32)*(y-self.magnet_origin[1])**2/dr**3 + dr[zero_coords[0][0]][zero_coords[0][1]][zero_coords[0][2]] = (x[1]-x[0])/1000#I still don't have a good way to approximate this point, so I just set a small difference to 0, notice that Bzxx is symmetric. + BZxx = ( + self.mu0_Ms + * self.Bzrr_np( + r=dr, + Z=dz, + R=self.magnet_radius, + L=L, + ep11=ep11, + ep21=ep21, + ep31=ep31, + ep12=ep12, + ep22=ep22, + ep32=ep32, + ) + * (x - self.magnet_origin[0]) ** 2 + / dr**2 + - self.mu0_Ms + * self.Bzr_np( + r=dr, + Z=dz, + R=self.magnet_radius, + L=L, + ep11=ep11, + ep21=ep21, + ep31=ep31, + ep12=ep12, + ep22=ep22, + ep32=ep32, + ) + * (y - self.magnet_origin[1]) ** 2 + / dr**3 + ) + return BZxx - \ No newline at end of file + else: + return ( + self.mu0_Ms + * self.Bzrr_np( + r=dr, + Z=dz, + R=self.magnet_radius, + L=L, + ep11=ep11, + ep21=ep21, + ep31=ep31, + ep12=ep12, + ep22=ep22, + ep32=ep32, + ) + * (x - self.magnet_origin[0]) ** 2 + / dr**2 + - self.mu0_Ms + * self.Bzr_np( + r=dr, + Z=dz, + R=self.magnet_radius, + L=L, + ep11=ep11, + ep21=ep21, + ep31=ep31, + ep12=ep12, + ep22=ep22, + ep32=ep32, + ) + * (y - self.magnet_origin[1]) ** 2 + / dr**3 + ) diff --git a/tests/test_component/test_magnet_cylinder.py b/tests/test_component/test_magnet_cylinder.py index 1135377..452fcaa 100644 --- a/tests/test_component/test_magnet_cylinder.py +++ b/tests/test_component/test_magnet_cylinder.py @@ -5,8 +5,11 @@ class TestCylinderMagnet: def setup_method(self): - self.magnet = CylinderMagnet(magnet_radius=0.5, magnet_length=10, magnet_origin=[0, 0, 0], mu0_Ms=1) + self.magnet = CylinderMagnet( + magnet_radius=0.5, magnet_length=10, magnet_origin=[0, 0, 0], mu0_Ms=1 + ) + # test the shape of the magnetic field def test_Bz_shape(self): grid = np.ogrid[-1:1:2j, -1:1:5j, -1:1:10j] Bz = self.magnet.Bz_method(grid[0], grid[1], grid[2]) @@ -22,23 +25,23 @@ def test_Bzxx_shape(self): Bzxx = self.magnet.Bzxx_method(grid[0], grid[1], grid[2]) assert Bzxx.shape == (2, 5, 10) + # test the symmetry of the magnetic field def test_Bz_symmetry(self): Bz1 = self.magnet.Bz_method(1, 2, 6) Bz2 = self.magnet.Bz_method(-1, 2, 6) assert np.allclose(Bz1, Bz2) - def test_Bzx_symmetry(self): Bzx1 = self.magnet.Bzx_method(1, 2, 6) Bzx2 = self.magnet.Bzx_method(-1, 2, 6) - assert np.allclose(Bzx1, -Bzx2) + assert np.allclose(Bzx1, -Bzx2) # Bzx is antisymmetric def test_Bzxx_symmetry(self): Bzxx1 = self.magnet.Bzxx_method(1, 2, 6) Bzxx2 = self.magnet.Bzxx_method(-1, 2, 6) - assert np.allclose(Bzxx1, Bzxx2) - + assert np.allclose(Bzxx1, Bzxx2) # Bzxx is symmetric + # test the value of the magnetic field def test_Bz_1(self): Bz = self.magnet.Bz_method(1, 2, 6) assert np.allclose(Bz, 0.00391404, atol=1e-5) @@ -53,7 +56,7 @@ def test_Bzxx_1(self): def test_Bz_2(self): Bz = self.magnet.Bz_method(10, 0, 0) - assert np.allclose(Bz,-0.00044788490737216163, atol=1e-5) + assert np.allclose(Bz, -0.00044788490737216163, atol=1e-5) def test_Bzx_2(self): Bzx = self.magnet.Bzx_method(10, 0, 0) @@ -61,10 +64,9 @@ def test_Bzx_2(self): def test_Bzxx_2(self): Bzxx = self.magnet.Bzxx_method(10, 0, 0) - assert np.allclose(Bzxx,-3.22679905171e-05, atol=1e-5) + assert np.allclose(Bzxx, -3.22679905171e-05, atol=1e-5) + # test the when x is 0, Bzx is 0 def test_Bzx_when_x_is_0(self): Bzx = self.magnet.Bzx_method(0, 10, 0) assert np.allclose(Bzx, 0, atol=1e-10) - - From f6e4a17cc4fe1c9956321ae196dae365c3e6230e Mon Sep 17 00:00:00 2001 From: Peter Sun Date: Tue, 15 Apr 2025 23:27:57 -0400 Subject: [PATCH 08/45] Modify component docstrings --- mrfmsim/component/cantilever.py | 9 +++++++-- mrfmsim/component/grid.py | 20 ++++++++++---------- mrfmsim/component/magnet.py | 17 +++++++---------- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/mrfmsim/component/cantilever.py b/mrfmsim/component/cantilever.py index 280925b..a04bfce 100644 --- a/mrfmsim/component/cantilever.py +++ b/mrfmsim/component/cantilever.py @@ -10,8 +10,13 @@ class Cantilever(ComponentBase): """Cantilever object. - :param float k: spring constant [aN/nm] - :param float f: mechanical resonance frequency [Hz] + :param float k_c: spring constant [aN/nm] + :param float f_c: mechanical resonance frequency [Hz] + + :ivar float k2f_modulated: spring constant to frequency ratio for modulated + cantilever (lockin) [Hz.nm/aN]p + :ivar float k2f: spring constant to frequency ratio for non-modulated + cantilever [Hz.nm/aN] """ k_c: float = field(metadata={"unit": "aN/nm", "format": ".3e"}) diff --git a/mrfmsim/component/grid.py b/mrfmsim/component/grid.py index e4ed68f..963b184 100644 --- a/mrfmsim/component/grid.py +++ b/mrfmsim/component/grid.py @@ -14,18 +14,18 @@ class Grid(ComponentBase): The grid array uses numpy's open mesh-grid, which has speed and storage benefits. - :param np.array length: array of lengths along (x, y, z) - :param np.array step: a list of step sizes - :param np.array origin: the grid origin - :param tuple[int] shape: grid dimension (number of points in x, y, z direction) - :param list step: grid setup size in x, y, z direction - :param list origin: grid origin - :param float voxel: the volume of each grid voxel - :param np.array range: range in (x, y, z direction), shape (3, 2) - :param np.array length: actual lengths of the grid. This is recalculated + :param ndarray grid_step: grid setup size in x, y, z direction + :param ndarray grid_origin: the grid origin + + :ivar ndarray grid_length: array of lengths along (x, y, z) + :ivar float grid_voxel: the volume of each grid voxel + :ivar ndarray grid_range: range in (x, y, z direction), shape (3, 2) + :ivar ndarray grid_length: actual lengths of the grid. This is recalculated based on the rounded value of grid shape and step size. + :ivar ndarray grid_extents: the grid extents in (x, y, z direction), shape (3, 2) + :ivar ndarray grid_array: the grid array in (x, y, z direction), shape (3, n) """ grid_shape: tuple[int] @@ -91,7 +91,7 @@ def extend_grid_by_length(self, ext_length): This is used to extend the grid by the cantilever motion. The length needs to be more than the step size to count. - :param int ext_pts: distance (one side) to extend along x direction + :param int ext_length: distance (one side) to extend along x direction (cantilever motion direction). The length should be a list of three dimensions. """ diff --git a/mrfmsim/component/magnet.py b/mrfmsim/component/magnet.py index 2b4e060..b0d3275 100644 --- a/mrfmsim/component/magnet.py +++ b/mrfmsim/component/magnet.py @@ -8,8 +8,8 @@ class SphereMagnet(ComponentBase): """Spherical magnet object with its Bz, Bzx, Bzxx calculations. - :param float radius: sphere magnet radius [nm] - :param list origin: the position of the magnet origin (x, y, z) + :param float magnet_radius: sphere magnet radius [nm] + :param list magnet_origin: the position of the magnet origin (x, y, z) :param float mu0_Ms: saturation magnetization [mT] """ @@ -60,7 +60,7 @@ def _bz(dx, dy, dz): :param dx: normalized distances to the center of the magnet in x :param dx: normalized distances to the center of the magnet in y :param dx: normalized distances to the center of the magnet in z - :type: np.array + :return: bz without pre-term :rtype: np.array """ @@ -111,7 +111,7 @@ def _bzx(dx, dy, dz): :param dx: normalized distances to the center of the magnet in x :param dy: normalized distances to the center of the magnet in y :param dz: normalized distances to the center of the magnet in z - :type: np.array + :return: bzx without pre-term :rtype: np.array """ @@ -163,7 +163,7 @@ def _bzxx(dx, dy, dz): :param dx: normalized distances to the center of the magnet in x :param dy: normalized distances to the center of the magnet in y :param dz: normalized distances to the center of the magnet in z - :type: np.array + :return: bzxx without pre-term :rtype: np.array """ @@ -180,12 +180,9 @@ def _bzxx(dx, dy, dz): class RectangularMagnet(ComponentBase): """Rectangular magnet object with the bz, bzx, bzxx calculations. - :param list length: length of rectangular magnet in (x, y, z) direction [nm] - :param list origin: the position of the magnet origin (x, y, z) + :param list magnet_length: length of rectangular magnet in (x, y, z) direction [nm] + :param list magnet_origin: the position of the magnet origin (x, y, z) :param float mu0_Ms: saturation magnetization [mT] - :ivar np.array _range: - [-xrange, +xrange, -yrange, +yrange, -zrange, zrange] - range in the x, y and z direction after the center point to the origin. """ magnet_length: list[float] = field(metadata={"unit": "nm", "format": ".1f"}) From c3c0afa2f0ff9095ac93faab4ad2a181bf84e57b Mon Sep 17 00:00:00 2001 From: SKeeTElor Date: Thu, 24 Apr 2025 12:39:26 -0400 Subject: [PATCH 09/45] Complete the CylinderMagnetIndirect class --- mrfmsim/component/magnet_cylinder.py | 180 ++++++++------------------- 1 file changed, 53 insertions(+), 127 deletions(-) diff --git a/mrfmsim/component/magnet_cylinder.py b/mrfmsim/component/magnet_cylinder.py index f9fe860..530696b 100644 --- a/mrfmsim/component/magnet_cylinder.py +++ b/mrfmsim/component/magnet_cylinder.py @@ -23,92 +23,6 @@ class CylinderMagnet(ComponentBase): ) mu0_Ms: float = field(metadata={"unit": "mT"}) - def __post_init__(self): - - # first use sympy to calculate the Bz, Bzr, Bzrr,the equation if from paper:https://doi.org/10.1016/j.jmmm.2018.02.003.(https://www.sciencedirect.com/science/article/pii/S0304885317334662), - # note that the def of n is different in the paper and the code, so we need to change the def of n in the code - - r, Z, R, L = sympy.symbols("r Z R L") - ep11, ep21, ep31 = sympy.symbols("ep11 ep21 ep31") - ep12, ep22, ep32 = sympy.symbols("ep12 ep22 ep32") - - g = (r - R) / (r + R) - - eps1 = Z + L - eps2 = Z - L - - alpha1 = 1 / sympy.sqrt(eps1**2 + (r + R) ** 2) - alpha2 = 1 / sympy.sqrt(eps2**2 + (r + R) ** 2) - - k1 = (eps1**2 + (r - R) ** 2) / (eps1**2 + (r + R) ** 2) - k2 = (eps2**2 + (r - R) ** 2) / (eps2**2 + (r + R) ** 2) - n = 1 - g**2 - - P21 = -g / (1 - g**2) * (elliptic_pi(n, 1 - k1) - elliptic_k(1 - k1)) - 1 / ( - 1 - g**2 - ) * (g**2 * elliptic_pi(n, 1 - k1) - elliptic_k(1 - k1)) - P22 = -g / (1 - g**2) * (elliptic_pi(n, 1 - k2) - elliptic_k(1 - k2)) - 1 / ( - 1 - g**2 - ) * (g**2 * elliptic_pi(n, 1 - k2) - elliptic_k(1 - k2)) - - Bz = (P21 * alpha1 * eps1 - P22 * eps2 * alpha2) * R / (r + R) / sympy.pi - Bzr = sympy.diff(Bz, r) - Bzrr = sympy.diff(Bzr, r) - - # use ep11, ep21, ep31, ep12, ep22, ep32 to replace the elliptic_k, elliptic_e, elliptic_pi, to avoid call elliptic_k, elliptic_e, elliptic_pi repeatedly - Bz_subs = Bz.subs( - { - sympy.elliptic_k(1 - k1): ep11, - sympy.elliptic_e(1 - k1): ep21, - sympy.elliptic_pi(n, 1 - k1): ep31, - sympy.elliptic_k(1 - k2): ep12, - sympy.elliptic_e(1 - k2): ep22, - sympy.elliptic_pi(n, 1 - k2): ep32, - } - ) - - Bzr_subs = Bzr.subs( - { - sympy.elliptic_k(1 - k1): ep11, - sympy.elliptic_e(1 - k1): ep21, - sympy.elliptic_pi(n, 1 - k1): ep31, - sympy.elliptic_k(1 - k2): ep12, - sympy.elliptic_e(1 - k2): ep22, - sympy.elliptic_pi(n, 1 - k2): ep32, - } - ) - - Bzrr_subs = Bzrr.subs( - { - sympy.elliptic_k(1 - k1): ep11, - sympy.elliptic_e(1 - k1): ep21, - sympy.elliptic_pi(n, 1 - k1): ep31, - sympy.elliptic_k(1 - k2): ep12, - sympy.elliptic_e(1 - k2): ep22, - sympy.elliptic_pi(n, 1 - k2): ep32, - } - ) - - special_functions = {"sqrt": np.sqrt, "pi": np.pi} - - # use sympy.lambdify to convert the sympy expression to a numpy function - self.Bz_np = sympy.lambdify( - (r, Z, R, L, ep11, ep21, ep31, ep12, ep22, ep32), - Bz_subs, - modules=[special_functions, "numpy"], - ) - self.Bzr_np = sympy.lambdify( - (r, Z, R, L, ep11, ep21, ep31, ep12, ep22, ep32), - Bzr_subs, - modules=[special_functions, "numpy"], - ) - self.Bzrr_np = sympy.lambdify( - (r, Z, R, L, ep11, ep21, ep31, ep12, ep22, ep32), - Bzrr_subs, - modules=[special_functions, "numpy"], - ) - - # use numpy to calculate the Bz, Bzx, Bzxx def Bz_method(self, x, y, z): r"""Calculate magnetic field :math:`B_z` [mT]. @@ -116,7 +30,21 @@ def Bz_method(self, x, y, z): The magnetic field is calculated as .. math:: - can be found in the paper:https://doi.org/10.1016/j.jmmm.2018.02.003.(https://www.sciencedirect.com/science/article/pii/S0304885317334662) + Bz = mu0_Ms * (P21 * alpha1 * eps1 - P22 * eps2 * alpha2) * R / (r + R) / pi + + in which: + eps1 = z + L/2 + eps2 = z - L/2 + k1 = (eps1**2 + (r - R) ** 2) / (eps1**2 + (r + R) ** 2) + k2 = (eps2**2 + (r - R) ** 2) / (eps2**2 + (r + R) ** 2) + g = (r - R) / (r + R) + n = 1 - g**2 + alpha1 = 1 / \sqrt{eps1**2 + (r + R) ** 2} + alpha2 = 1 / \sqrt{eps2**2 + (r + R) ** 2} + P21 = -g / (1 - g**2) * (elliptic_pi(n, 1 - k1) - elliptic_k(1 - k1)) - 1 / (1 - g**2 ) * (g**2 * elliptic_pi(n, 1 - k1) - elliptic_k(1 - k1)) + P22 = -g / (1 - g**2) * (elliptic_pi(n, 1 - k2) - elliptic_k(1 - k2)) - 1 / (1 - g**2 ) * (g**2 * elliptic_pi(n, 1 - k2) - elliptic_k(1 - k2)) + note that: + the def of n (in elliptic integral) is different in the paper and the code, so we need to change the def of n in the code. :param float x: x coordinate of sample grid [nm] :param float y: y coordinate of sample grid [nm] @@ -131,6 +59,11 @@ def Bz_method(self, x, y, z): distances to the center of the magnet; :math:`\mu_0 M_s` is the magnetic sphere's saturation magnetization in mT. + + There is a singularity when x^2+y^2==0, so we need to manually replace B_z with its corresponding algebraic form: + + .. math:: + Bz = \dfrac{\mu0_Ms}{2} * \dfrac{z + L/2}{\sqrt{(z + L/2)**2 + R**2}} - \dfrac{\mu0_Ms}{2} * \dfrac{z - L/2}{\sqrt{(z - L/2)**2 + R**2}} """ def ellipiticPi(n, m): @@ -142,10 +75,9 @@ def ellipiticPi(n, m): (x - self.magnet_origin[0]) ** 2 + (y - self.magnet_origin[1]) ** 2 ) dz = z - self.magnet_origin[2] - L = self.magnet_length / 2 g = (dr - self.magnet_radius) / (dr + self.magnet_radius) - eps1 = z + L - eps2 = z - L + eps1 = z + self.magnet_length / 2 + eps2 = z - self.magnet_length / 2 k1 = (eps1**2 + (dr - self.magnet_radius) ** 2) / ( eps1**2 + (dr + self.magnet_radius) ** 2 ) @@ -154,7 +86,6 @@ def ellipiticPi(n, m): ) n = 1 - g**2 - # then we calculate the ep11, ep21, ep31, ep12, ep22, ep32, We will precompute the numerical values of these elliptic functions and pass them as inputs to the functions to avoid repeatedly calling the elliptic functions and thus reduce runtime. However, this will increase memory usage. ep11 = ellipk(1 - k1) ep21 = ellipe(1 - k1) ep31 = ellipiticPi(n, 1 - k1) @@ -167,11 +98,9 @@ def ellipiticPi(n, m): if zero_coords.size > 0: dr[zero_coords[0][0]][zero_coords[0][1]][zero_coords[0][2]] = np.nan - BZ = self.mu0_Ms * self.Bz_np( + BZ = self.mu0_Ms * self._Bz_np( r=dr, Z=dz, - R=self.magnet_radius, - L=L, ep11=ep11, ep21=ep21, ep31=ep31, @@ -192,15 +121,13 @@ def ellipiticPi(n, m): (dz - self.magnet_length / 2) ** 2 + (self.magnet_radius) ** 2 ) ) - )#Along the Z-axis, B_z reduces to an algebraic function. Since this point is a singularity in the original expression, we need to manually replace B_z with its corresponding algebraic form. + ) return BZ else: - return self.mu0_Ms * self.Bz_np( + return self.mu0_Ms * self._Bz_np( r=dr, Z=dz, - R=self.magnet_radius, - L=L, ep11=ep11, ep21=ep21, ep31=ep31, @@ -215,7 +142,8 @@ def Bzx_method(self, x, y, z): The magnetic field is calculated as .. math: - using sympy directly calculate the derivative of Bz + \dfrac{\partial B_z}{\partial x} = \dfrac{\partial B_z}{\partial r} * \dfrac{\partial r}{\partial x}+\dfrac{\partial B_z}{\partial z} * \dfrac{\partial z}{\partial x} + =\dfrac{\partial B_z}{\partial r} * \dfrac{x}{r} :param float x: x coordinate of sample grid [nm] :param float y: y coordinate of sample grid [nm] @@ -242,10 +170,9 @@ def ellipiticPi(n, m): dz = z - self.magnet_origin[2] zero_coords = np.argwhere(dr == 0) - L = self.magnet_length / 2 g = (dr - self.magnet_radius) / (dr + self.magnet_radius) - eps1 = z + L - eps2 = z - L + eps1 = z + self.magnet_length / 2 + eps2 = z - self.magnet_length / 2 k1 = (eps1**2 + (dr - self.magnet_radius) ** 2) / ( eps1**2 + (dr + self.magnet_radius) ** 2 ) @@ -254,7 +181,6 @@ def ellipiticPi(n, m): ) n = 1 - g**2 - # then we calculate the ep11, ep21, ep31, ep12, ep22, ep32, We will precompute the numerical values of these elliptic functions and pass them as inputs to the functions to avoid repeatedly calling the elliptic functions and thus reduce runtime. However, this will increase memory usage. ep11 = ellipk(1 - k1) ep21 = ellipe(1 - k1) ep31 = ellipiticPi(n, 1 - k1) @@ -267,11 +193,9 @@ def ellipiticPi(n, m): dr[zero_coords[0][0]][zero_coords[0][1]][zero_coords[0][2]] = np.nan BZr = ( self.mu0_Ms - * self.Bzr_np( + * self._Bzr_np( r=dr, Z=dz, - R=self.magnet_radius, - L=L, ep11=ep11, ep21=ep21, ep31=ep31, @@ -282,17 +206,15 @@ def ellipiticPi(n, m): * (x - self.magnet_origin[0]) / dr ) - BZr[zero_coords[0][0]][zero_coords[0][1]][:] = np.zeros(len(dz)) #Along the Z-axis, B_zr would be 0 due to the symmetry + BZr[zero_coords[0][0]][zero_coords[0][1]][:] = np.zeros(len(dz)) return BZr else: return ( self.mu0_Ms - * self.Bzr_np( + * self._Bzr_np( r=dr, Z=dz, - R=self.magnet_radius, - L=L, ep11=ep11, ep21=ep21, ep31=ep31, @@ -339,10 +261,9 @@ def ellipiticPi(n, m): zero_coords = np.argwhere(dr == 0) - L = self.magnet_length / 2 g = (dr - self.magnet_radius) / (dr + self.magnet_radius) - eps1 = z + L - eps2 = z - L + eps1 = z + self.magnet_length / 2 + eps2 = z - self.magnet_length / 2 k1 = (eps1**2 + (dr - self.magnet_radius) ** 2) / ( eps1**2 + (dr + self.magnet_radius) ** 2 ) @@ -351,7 +272,6 @@ def ellipiticPi(n, m): ) n = 1 - g**2 - # then we calculate the ep11, ep21, ep31, ep12, ep22, ep32, We will precompute the numerical values of these elliptic functions and pass them as inputs to the functions to avoid repeatedly calling the elliptic functions and thus reduce runtime. However, this will increase memory usage. ep11 = ellipk(1 - k1) ep21 = ellipe(1 - k1) ep31 = ellipiticPi(n, 1 - k1) @@ -361,14 +281,14 @@ def ellipiticPi(n, m): ep32 = ellipiticPi(n, 1 - k2) if zero_coords.size > 0: - dr[zero_coords[0][0]][zero_coords[0][1]][zero_coords[0][2]] = (x[1]-x[0])/1000#I still don't have a good way to approximate this point, so I just set a small difference to 0, notice that Bzxx is symmetric. + dr[zero_coords[0][0]][zero_coords[0][1]][zero_coords[0][2]] = ( + x[1] - x[0] + ) / 1000 # I still don't have a good way to approximate this point, so I just set a small difference to 0, notice that Bzxx is symmetric. BZxx = ( self.mu0_Ms - * self.Bzrr_np( + * self._Bzrr_np( r=dr, Z=dz, - R=self.magnet_radius, - L=L, ep11=ep11, ep21=ep21, ep31=ep31, @@ -379,11 +299,9 @@ def ellipiticPi(n, m): * (x - self.magnet_origin[0]) ** 2 / dr**2 - self.mu0_Ms - * self.Bzr_np( + * self._Bzr_np( r=dr, Z=dz, - R=self.magnet_radius, - L=L, ep11=ep11, ep21=ep21, ep31=ep31, @@ -399,11 +317,9 @@ def ellipiticPi(n, m): else: return ( self.mu0_Ms - * self.Bzrr_np( + * self._Bzrr_np( r=dr, Z=dz, - R=self.magnet_radius, - L=L, ep11=ep11, ep21=ep21, ep31=ep31, @@ -414,11 +330,9 @@ def ellipiticPi(n, m): * (x - self.magnet_origin[0]) ** 2 / dr**2 - self.mu0_Ms - * self.Bzr_np( + * self._Bzr_np( r=dr, Z=dz, - R=self.magnet_radius, - L=L, ep11=ep11, ep21=ep21, ep31=ep31, @@ -429,3 +343,15 @@ def ellipiticPi(n, m): * (y - self.magnet_origin[1]) ** 2 / dr**3 ) + + """_BZ_np,_Bzr_np,_Bzrr_np is terribly long, they are calculated with sympy. + """ + + def _Bz_np(self, r, Z, ep11, ep21, ep31, ep12, ep22, ep32): + return self.magnet_radius*(-(-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/np.sqrt((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/np.sqrt((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(np.pi*(self.magnet_radius + r)) + + def _Bzr_np(self, r, Z, ep11, ep21, ep31, ep12, ep22, ep32): + return self.magnet_radius*(-(-self.magnet_length/2 + Z)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) - (-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + (-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (ep32*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - (-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/np.sqrt((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (self.magnet_length/2 + Z)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) + (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + (-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (ep31*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - (-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/np.sqrt((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(np.pi*(self.magnet_radius + r)) - self.magnet_radius*(-(-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/np.sqrt((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/np.sqrt((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(np.pi*(self.magnet_radius + r)**2) + + def _Bzrr_np(self, r, Z, ep11, ep21, ep31, ep12, ep22, ep32): + return self.magnet_radius*(-(-self.magnet_length/2 + Z)*(-3*self.magnet_radius - 3*r)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(5/2) - 2*(-self.magnet_length/2 + Z)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + (-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (ep32*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - (-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) + (-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) - (-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**3) - (-self.magnet_radius + r)*(-ep12 + ep32)*(-4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2/(self.magnet_radius + r)**2)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - 2*(-self.magnet_radius + r)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(2*self.magnet_radius - 2*r)*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2) - (2*self.magnet_radius + 2*r)*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-ep12*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - ep12*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)**2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep22*(2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2 - ep22*(2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) - (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2 - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep12*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep32*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep32*((-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) + ((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)*(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + ((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))*(2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2) - (self.magnet_radius + r)**2*(4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 - 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 - 2/(self.magnet_radius + r)**2)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (2*self.magnet_radius + 2*r)*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) + 2*(self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**3*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + 2*(-self.magnet_radius + r)*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) + 2*(-self.magnet_radius + r)*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - 2*(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)**3*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**3 - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*(-4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - 2*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep32*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (-4*ep32*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2*ep32/(self.magnet_radius + r)**2 + 2*(-2*self.magnet_radius + 2*r)*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 + (-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep22*(2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2 - ep22*(2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) - (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2 - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep12*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep32*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep32*((-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) + ((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)*(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + ((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))*(2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2) - (self.magnet_radius + r)**2*(4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 - 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 - 2/(self.magnet_radius + r)**2)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (2*self.magnet_radius + 2*r)*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) + 2*(self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**3*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**3 - (2*self.magnet_radius - 2*r)*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2) - (2*self.magnet_radius + 2*r)*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-ep12*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - ep12*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)**2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - 2*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - 2*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + 2*(-ep12 + ep32)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/np.sqrt((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (self.magnet_length/2 + Z)*(-3*self.magnet_radius - 3*r)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(5/2) + 2*(self.magnet_length/2 + Z)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + (-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (ep31*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - (-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) - (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) + (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**3) - (-self.magnet_radius + r)*(-ep11 + ep31)*(-4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2/(self.magnet_radius + r)**2)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - 2*(-self.magnet_radius + r)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(2*self.magnet_radius - 2*r)*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2) - (2*self.magnet_radius + 2*r)*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-ep11*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - ep11*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)**2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep21*(2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2 - ep21*(2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) - (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2 - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep11*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep31*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep31*((-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) + ((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)*(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + ((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))*(2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2) - (self.magnet_radius + r)**2*(4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 - 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 - 2/(self.magnet_radius + r)**2)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (2*self.magnet_radius + 2*r)*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) + 2*(self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**3*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + 2*(-self.magnet_radius + r)*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) + 2*(-self.magnet_radius + r)*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - 2*(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)**3*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**3 - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*(-4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - 2*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep31*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (-4*ep31*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2*ep31/(self.magnet_radius + r)**2 + 2*(-2*self.magnet_radius + 2*r)*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 + (-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep21*(2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2 - ep21*(2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) - (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2 - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep11*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep31*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep31*((-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) + ((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)*(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + ((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))*(2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2) - (self.magnet_radius + r)**2*(4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 - 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 - 2/(self.magnet_radius + r)**2)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (2*self.magnet_radius + 2*r)*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) + 2*(self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**3*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**3 - (2*self.magnet_radius - 2*r)*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2) - (2*self.magnet_radius + 2*r)*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-ep11*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - ep11*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)**2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - 2*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - 2*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + 2*(-ep11 + ep31)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/np.sqrt((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(np.pi*(self.magnet_radius + r)) - 2*self.magnet_radius*(-(-self.magnet_length/2 + Z)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) - (-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + (-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (ep32*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - (-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/np.sqrt((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (self.magnet_length/2 + Z)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) + (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + (-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (ep31*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - (-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/np.sqrt((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(np.pi*(self.magnet_radius + r)**2) + 2*self.magnet_radius*(-(-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/np.sqrt((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/np.sqrt((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(np.pi*(self.magnet_radius + r)**3) \ No newline at end of file From 443d328161089e646e928d957e3c42658cf049e1 Mon Sep 17 00:00:00 2001 From: SKeeTElor Date: Thu, 24 Apr 2025 12:44:15 -0400 Subject: [PATCH 10/45] Now start to implement the approximate calculation of the cylinder magnet field. --- mrfmsim/component/__init__.py | 1 + mrfmsim/component/magnet_cylinder_indirect.py | 456 ++++++++++++++++++ 2 files changed, 457 insertions(+) create mode 100644 mrfmsim/component/magnet_cylinder_indirect.py diff --git a/mrfmsim/component/__init__.py b/mrfmsim/component/__init__.py index 422130e..bf831a3 100644 --- a/mrfmsim/component/__init__.py +++ b/mrfmsim/component/__init__.py @@ -4,3 +4,4 @@ from .grid import Grid from .sample import Sample from .magnet_cylinder import CylinderMagnet +from .magnet_cylinder_indirect import CylinderMagnetIndirect diff --git a/mrfmsim/component/magnet_cylinder_indirect.py b/mrfmsim/component/magnet_cylinder_indirect.py new file mode 100644 index 0000000..f404ee2 --- /dev/null +++ b/mrfmsim/component/magnet_cylinder_indirect.py @@ -0,0 +1,456 @@ +import numpy as np +import sympy +from sympy import elliptic_k, elliptic_pi +from scipy.special import elliprf, ellipk, elliprj, ellipe +from dataclasses import dataclass, field +from mrfmsim.component import ComponentBase + + +@dataclass +class CylinderMagnetIndirect(ComponentBase): + """Cylinder magnet object with its Bz, Bzx, Bzxx calculations. + + :param float radius: cylinder magnet radius [nm] !!!There would ba a singularity when x^2+y^2=R^2, so set a small difference to R!!! Also when x^2+y^2=0, B_zxx would run into a singularity, try to avoid this point. + :param float length: cylinder magnet length [nm] + :param tuple origin: the position of the magnet origin (x, y, z) + :param float mu0_Ms: permeability of free space [H/m] + """ + + magnet_radius: float = field(metadata={"unit": "nm", "format": ".1f"}) + magnet_length: float = field(metadata={"unit": "nm", "format": ".1f"}) + magnet_origin: tuple[float, float, float] = field( + metadata={"unit": "nm", "format": ".1f"} + ) + mu0_Ms: float = field(metadata={"unit": "mT"}) + + def __post_init__(self): + r""" + This function is used to calculate the Bz, Bzr, Bzrr of the cylinder magnet using sympy. Due to the complexity of the expression, we use sympy to calculate the expression and then use sympy.lambdify to convert the expression to a numpy function. + first use sympy to calculate the Bz, Bzr, Bzrr,the equation if from paper:https://doi.org/10.1016/j.jmmm.2018.02.003.(https://www.sciencedirect.com/science/article/pii/S0304885317334662), (note that the def of n is different in the paper and the code, so we need to change the def of n in the code). + Also, we use ep11, ep21, ep31, ep12, ep22, ep32 to replace the elliptic_k, elliptic_e, elliptic_pi, to avoid call elliptic_k, elliptic_e, elliptic_pi repeatedly. + + variables: + r: radius of the sample grid + Z: z coordinate of the sample grid + R: radius of the magnet + L: length of the magnet + ep11, ep21, ep31, ep12, ep22, ep32: precomputed elliptic functions + """ + + r, Z, R, L = sympy.symbols("r Z R L") + ep11, ep21, ep31 = sympy.symbols("ep11 ep21 ep31") + ep12, ep22, ep32 = sympy.symbols("ep12 ep22 ep32") + + g = (r - R) / (r + R) + + eps1 = Z + L + eps2 = Z - L + + alpha1 = 1 / sympy.sqrt(eps1**2 + (r + R) ** 2) + alpha2 = 1 / sympy.sqrt(eps2**2 + (r + R) ** 2) + + k1 = (eps1**2 + (r - R) ** 2) / (eps1**2 + (r + R) ** 2) + k2 = (eps2**2 + (r - R) ** 2) / (eps2**2 + (r + R) ** 2) + n = 1 - g**2 + + P21 = -g / (1 - g**2) * (elliptic_pi(n, 1 - k1) - elliptic_k(1 - k1)) - 1 / ( + 1 - g**2 + ) * (g**2 * elliptic_pi(n, 1 - k1) - elliptic_k(1 - k1)) + P22 = -g / (1 - g**2) * (elliptic_pi(n, 1 - k2) - elliptic_k(1 - k2)) - 1 / ( + 1 - g**2 + ) * (g**2 * elliptic_pi(n, 1 - k2) - elliptic_k(1 - k2)) + + Bz = (P21 * alpha1 * eps1 - P22 * eps2 * alpha2) * R / (r + R) / sympy.pi + Bzr = sympy.diff(Bz, r) + Bzrr = sympy.diff(Bzr, r) + + Bz_subs = Bz.subs( + { + sympy.elliptic_k(1 - k1): ep11, + sympy.elliptic_e(1 - k1): ep21, + sympy.elliptic_pi(n, 1 - k1): ep31, + sympy.elliptic_k(1 - k2): ep12, + sympy.elliptic_e(1 - k2): ep22, + sympy.elliptic_pi(n, 1 - k2): ep32, + } + ) + + Bzr_subs = Bzr.subs( + { + sympy.elliptic_k(1 - k1): ep11, + sympy.elliptic_e(1 - k1): ep21, + sympy.elliptic_pi(n, 1 - k1): ep31, + sympy.elliptic_k(1 - k2): ep12, + sympy.elliptic_e(1 - k2): ep22, + sympy.elliptic_pi(n, 1 - k2): ep32, + } + ) + + Bzrr_subs = Bzrr.subs( + { + sympy.elliptic_k(1 - k1): ep11, + sympy.elliptic_e(1 - k1): ep21, + sympy.elliptic_pi(n, 1 - k1): ep31, + sympy.elliptic_k(1 - k2): ep12, + sympy.elliptic_e(1 - k2): ep22, + sympy.elliptic_pi(n, 1 - k2): ep32, + } + ) + + special_functions = {"sqrt": np.sqrt, "pi": np.pi} + + self.Bz_np = sympy.lambdify( + (r, Z, R, L, ep11, ep21, ep31, ep12, ep22, ep32), + Bz_subs, + modules=[special_functions, "numpy"], + ) + self.Bzr_np = sympy.lambdify( + (r, Z, R, L, ep11, ep21, ep31, ep12, ep22, ep32), + Bzr_subs, + modules=[special_functions, "numpy"], + ) + self.Bzrr_np = sympy.lambdify( + (r, Z, R, L, ep11, ep21, ep31, ep12, ep22, ep32), + Bzrr_subs, + modules=[special_functions, "numpy"], + ) + + def Bz_method(self, x, y, z): + r"""Calculate magnetic field :math:`B_z` [mT]. + + The magnetic field is calculated as + + .. math:: + Bz = mu0_Ms * (P21 * alpha1 * eps1 - P22 * eps2 * alpha2) * R / (r + R) / pi + + in which: + eps1 = z + L/2 + eps2 = z - L/2 + k1 = (eps1**2 + (r - R) ** 2) / (eps1**2 + (r + R) ** 2) + k2 = (eps2**2 + (r - R) ** 2) / (eps2**2 + (r + R) ** 2) + g = (r - R) / (r + R) + n = 1 - g**2 + alpha1 = 1 / \sqrt{eps1**2 + (r + R) ** 2} + alpha2 = 1 / \sqrt{eps2**2 + (r + R) ** 2} + P21 = -g / (1 - g**2) * (elliptic_pi(n, 1 - k1) - elliptic_k(1 - k1)) - 1 / (1 - g**2 ) * (g**2 * elliptic_pi(n, 1 - k1) - elliptic_k(1 - k1)) + P22 = -g / (1 - g**2) * (elliptic_pi(n, 1 - k2) - elliptic_k(1 - k2)) - 1 / (1 - g**2 ) * (g**2 * elliptic_pi(n, 1 - k2) - elliptic_k(1 - k2)) + note that: + the def of n (in elliptic integral) is different in the paper and the code, so we need to change the def of n in the code. + + :param float x: x coordinate of sample grid [nm] + :param float y: y coordinate of sample grid [nm] + :param float z: z coordinate of sample grid [nm] + + + Here :math:`(x,y,z)` is the location at which we want to know the field; + :math:`r` is the radius of the magnet; :math:`r**2 = x**2 + y**2`; + :math 'dx = x-x_0' + :math 'dy = y-y_0' + :math 'dz = z-z_0' + distances to the center of the magnet; + :math:`\mu_0 M_s` is the magnetic sphere's saturation + magnetization in mT. + + There is a singularity when x^2+y^2==0, so we need to manually replace B_z with its corresponding algebraic form: + + .. math:: + Bz = \dfrac{\mu0_Ms}{2} * \dfrac{z + L/2}{\sqrt{(z + L/2)**2 + R**2}} - \dfrac{\mu0_Ms}{2} * \dfrac{z - L/2}{\sqrt{(z - L/2)**2 + R**2}} + """ + + def ellipiticPi(n, m): + return elliprf(0.0, 1.0 - m, 1.0) + (n / 3.0) * elliprj( + 0.0, 1.0 - m, 1.0, 1.0 - n + ) + + dr = np.sqrt( + (x - self.magnet_origin[0]) ** 2 + (y - self.magnet_origin[1]) ** 2 + ) + dz = z - self.magnet_origin[2] + L = self.magnet_length / 2 + g = (dr - self.magnet_radius) / (dr + self.magnet_radius) + eps1 = z + L + eps2 = z - L + k1 = (eps1**2 + (dr - self.magnet_radius) ** 2) / ( + eps1**2 + (dr + self.magnet_radius) ** 2 + ) + k2 = (eps2**2 + (dr - self.magnet_radius) ** 2) / ( + eps2**2 + (dr + self.magnet_radius) ** 2 + ) + n = 1 - g**2 + + ep11 = ellipk(1 - k1) + ep21 = ellipe(1 - k1) + ep31 = ellipiticPi(n, 1 - k1) + + ep12 = ellipk(1 - k2) + ep22 = ellipe(1 - k2) + ep32 = ellipiticPi(n, 1 - k2) + + zero_coords = np.argwhere(dr == 0) + + if zero_coords.size > 0: + dr[zero_coords[0][0]][zero_coords[0][1]][zero_coords[0][2]] = np.nan + BZ = self.mu0_Ms * self.Bz_np( + r=dr, + Z=dz, + R=self.magnet_radius, + L=L, + ep11=ep11, + ep21=ep21, + ep31=ep31, + ep12=ep12, + ep22=ep22, + ep32=ep32, + ) + BZ[zero_coords[0][0]][zero_coords[0][1]][:] = ( + self.mu0_Ms + / 2 + * ( + (dz + self.magnet_length / 2) + / np.sqrt( + (dz + self.magnet_length / 2) ** 2 + (self.magnet_radius) ** 2 + ) + - (dz - self.magnet_length / 2) + / np.sqrt( + (dz - self.magnet_length / 2) ** 2 + (self.magnet_radius) ** 2 + ) + ) + ) + return BZ + + else: + return self.mu0_Ms * self.Bz_np( + r=dr, + Z=dz, + R=self.magnet_radius, + L=L, + ep11=ep11, + ep21=ep21, + ep31=ep31, + ep12=ep12, + ep22=ep22, + ep32=ep32, + ) + + def Bzx_method(self, x, y, z): + r"""Calculate magnetic field :math:`B_z` [mT]. + + The magnetic field is calculated as + + .. math: + \dfrac{\partial B_z}{\partial x} = \dfrac{\partial B_z}{\partial r} * \dfrac{\partial r}{\partial x}+\dfrac{\partial B_z}{\partial z} * \dfrac{\partial z}{\partial x} + =\dfrac{\partial B_z}{\partial r} * \dfrac{x}{r} + + :param float x: x coordinate of sample grid [nm] + :param float y: y coordinate of sample grid [nm] + :param float z: z coordinate of sample grid [nm] + + Here :math:`(x,y,z)` is the location at which we want to know the field; + :math:`r` is the radius of the magnet; :math:`r**2 = x**2 + y**2`; + :math 'dx = x-x_0' + :math 'dy = y-y_0' + :math 'dz = z-z_0' + distances to the center of the magnet; + :math:`\mu_0 M_s` is the magnetic sphere's saturation + magnetization in mT. + """ + + def ellipiticPi(n, m): + return elliprf(0.0, 1.0 - m, 1.0) + (n / 3.0) * elliprj( + 0.0, 1.0 - m, 1.0, 1.0 - n + ) + + dr = np.sqrt( + (x - self.magnet_origin[0]) ** 2 + (y - self.magnet_origin[1]) ** 2 + ) + dz = z - self.magnet_origin[2] + zero_coords = np.argwhere(dr == 0) + + L = self.magnet_length / 2 + g = (dr - self.magnet_radius) / (dr + self.magnet_radius) + eps1 = z + L + eps2 = z - L + k1 = (eps1**2 + (dr - self.magnet_radius) ** 2) / ( + eps1**2 + (dr + self.magnet_radius) ** 2 + ) + k2 = (eps2**2 + (dr - self.magnet_radius) ** 2) / ( + eps2**2 + (dr + self.magnet_radius) ** 2 + ) + n = 1 - g**2 + + ep11 = ellipk(1 - k1) + ep21 = ellipe(1 - k1) + ep31 = ellipiticPi(n, 1 - k1) + + ep12 = ellipk(1 - k2) + ep22 = ellipe(1 - k2) + ep32 = ellipiticPi(n, 1 - k2) + + if zero_coords.size > 0: + dr[zero_coords[0][0]][zero_coords[0][1]][zero_coords[0][2]] = np.nan + BZr = ( + self.mu0_Ms + * self.Bzr_np( + r=dr, + Z=dz, + R=self.magnet_radius, + L=L, + ep11=ep11, + ep21=ep21, + ep31=ep31, + ep12=ep12, + ep22=ep22, + ep32=ep32, + ) + * (x - self.magnet_origin[0]) + / dr + ) + BZr[zero_coords[0][0]][zero_coords[0][1]][:] = np.zeros(len(dz)) + return BZr + + else: + return ( + self.mu0_Ms + * self.Bzr_np( + r=dr, + Z=dz, + R=self.magnet_radius, + L=L, + ep11=ep11, + ep21=ep21, + ep31=ep31, + ep12=ep12, + ep22=ep22, + ep32=ep32, + ) + * (x - self.magnet_origin[0]) + / dr + ) + + def Bzxx_method(self, x, y, z): + r"""Calculate magnetic field :math:`B_z` [mT]. + + The magnetic field is calculated as + + .. math: + using sympy directly calculate the derivative of Bzr + + :param float x: x coordinate of sample grid [nm] + :param float y: y coordinate of sample grid [nm] + :param float z: z coordinate of sample grid [nm] + + + Here :math:`(x,y,z)` is the location at which we want to know the field; + :math:`r` is the radius of the magnet; :math:`r**2 = x**2 + y**2`; + :math 'dx = x-x_0' + :math 'dy = y-y_0' + :math 'dz = z-z_0' + distances to the center of the magnet; + :math:`\mu_0 M_s` is the magnetic sphere's saturation + magnetization in mT. + """ + + def ellipiticPi(n, m): + return elliprf(0.0, 1.0 - m, 1.0) + (n / 3.0) * elliprj( + 0.0, 1.0 - m, 1.0, 1.0 - n + ) + + dr = np.sqrt( + (x - self.magnet_origin[0]) ** 2 + (y - self.magnet_origin[1]) ** 2 + ) + dz = z - self.magnet_origin[2] + + zero_coords = np.argwhere(dr == 0) + + L = self.magnet_length / 2 + g = (dr - self.magnet_radius) / (dr + self.magnet_radius) + eps1 = z + L + eps2 = z - L + k1 = (eps1**2 + (dr - self.magnet_radius) ** 2) / ( + eps1**2 + (dr + self.magnet_radius) ** 2 + ) + k2 = (eps2**2 + (dr - self.magnet_radius) ** 2) / ( + eps2**2 + (dr + self.magnet_radius) ** 2 + ) + n = 1 - g**2 + + # then we calculate the ep11, ep21, ep31, ep12, ep22, ep32, We will precompute the numerical values of these elliptic functions and pass them as inputs to the functions to avoid repeatedly calling the elliptic functions and thus reduce runtime. However, this will increase memory usage. + ep11 = ellipk(1 - k1) + ep21 = ellipe(1 - k1) + ep31 = ellipiticPi(n, 1 - k1) + + ep12 = ellipk(1 - k2) + ep22 = ellipe(1 - k2) + ep32 = ellipiticPi(n, 1 - k2) + + if zero_coords.size > 0: + dr[zero_coords[0][0]][zero_coords[0][1]][zero_coords[0][2]] = ( + x[1] - x[0] + ) / 1000 # I still don't have a good way to approximate this point, so I just set a small difference to 0, notice that Bzxx is symmetric. + BZxx = ( + self.mu0_Ms + * self.Bzrr_np( + r=dr, + Z=dz, + R=self.magnet_radius, + L=L, + ep11=ep11, + ep21=ep21, + ep31=ep31, + ep12=ep12, + ep22=ep22, + ep32=ep32, + ) + * (x - self.magnet_origin[0]) ** 2 + / dr**2 + - self.mu0_Ms + * self.Bzr_np( + r=dr, + Z=dz, + R=self.magnet_radius, + L=L, + ep11=ep11, + ep21=ep21, + ep31=ep31, + ep12=ep12, + ep22=ep22, + ep32=ep32, + ) + * (y - self.magnet_origin[1]) ** 2 + / dr**3 + ) + return BZxx + + else: + return ( + self.mu0_Ms + * self.Bzrr_np( + r=dr, + Z=dz, + R=self.magnet_radius, + L=L, + ep11=ep11, + ep21=ep21, + ep31=ep31, + ep12=ep12, + ep22=ep22, + ep32=ep32, + ) + * (x - self.magnet_origin[0]) ** 2 + / dr**2 + - self.mu0_Ms + * self.Bzr_np( + r=dr, + Z=dz, + R=self.magnet_radius, + L=L, + ep11=ep11, + ep21=ep21, + ep31=ep31, + ep12=ep12, + ep22=ep22, + ep32=ep32, + ) + * (y - self.magnet_origin[1]) ** 2 + / dr**3 + ) From f8de1c584c866092afd2427f0e0a311277a79e0d Mon Sep 17 00:00:00 2001 From: SKeeTElor Date: Fri, 25 Apr 2025 14:36:44 -0400 Subject: [PATCH 11/45] I have add a new component for the cylinder magnet approximation. Also I have sloved a bug in the magnet_cylinder.py. -Now I am currently using 11 cuboids to approximate a cylinder. When viewed from the vertical direction, 11 rectangles are arranged side by side to simulate a circular shape. After testing, the relative error in regions with strong signals is less than 1%, and the runtime has been reduced by nearly 100 times. I have also written the corresponding test files. -I discovered a bug in the old CylinderMagnet class: I had forgotten to account for the offset of the z-coordinate relative to the origin. This issue has now been fixed. --- mrfmsim/component/__init__.py | 2 +- mrfmsim/component/magnet_cylinder.py | 24 +- mrfmsim/component/magnet_cylinder_approx.py | 568 ++++++++++++++++++ mrfmsim/component/magnet_cylinder_indirect.py | 456 -------------- .../test_magnet_cylinder_approx.py | 88 +++ 5 files changed, 669 insertions(+), 469 deletions(-) create mode 100644 mrfmsim/component/magnet_cylinder_approx.py delete mode 100644 mrfmsim/component/magnet_cylinder_indirect.py create mode 100644 tests/test_component/test_magnet_cylinder_approx.py diff --git a/mrfmsim/component/__init__.py b/mrfmsim/component/__init__.py index bf831a3..057621e 100644 --- a/mrfmsim/component/__init__.py +++ b/mrfmsim/component/__init__.py @@ -4,4 +4,4 @@ from .grid import Grid from .sample import Sample from .magnet_cylinder import CylinderMagnet -from .magnet_cylinder_indirect import CylinderMagnetIndirect +from .magnet_cylinder_approx import CylinderMagnetApproxByRectangularMagnet diff --git a/mrfmsim/component/magnet_cylinder.py b/mrfmsim/component/magnet_cylinder.py index 530696b..d2bf7af 100644 --- a/mrfmsim/component/magnet_cylinder.py +++ b/mrfmsim/component/magnet_cylinder.py @@ -1,6 +1,5 @@ import numpy as np -import sympy -from sympy import elliptic_k, elliptic_pi +import numba as nb from scipy.special import elliprf, ellipk, elliprj, ellipe from dataclasses import dataclass, field from mrfmsim.component import ComponentBase @@ -76,8 +75,8 @@ def ellipiticPi(n, m): ) dz = z - self.magnet_origin[2] g = (dr - self.magnet_radius) / (dr + self.magnet_radius) - eps1 = z + self.magnet_length / 2 - eps2 = z - self.magnet_length / 2 + eps1 = dz + self.magnet_length / 2 + eps2 = dz - self.magnet_length / 2 k1 = (eps1**2 + (dr - self.magnet_radius) ** 2) / ( eps1**2 + (dr + self.magnet_radius) ** 2 ) @@ -171,8 +170,8 @@ def ellipiticPi(n, m): zero_coords = np.argwhere(dr == 0) g = (dr - self.magnet_radius) / (dr + self.magnet_radius) - eps1 = z + self.magnet_length / 2 - eps2 = z - self.magnet_length / 2 + eps1 = dz + self.magnet_length / 2 + eps2 = dz - self.magnet_length / 2 k1 = (eps1**2 + (dr - self.magnet_radius) ** 2) / ( eps1**2 + (dr + self.magnet_radius) ** 2 ) @@ -262,8 +261,8 @@ def ellipiticPi(n, m): zero_coords = np.argwhere(dr == 0) g = (dr - self.magnet_radius) / (dr + self.magnet_radius) - eps1 = z + self.magnet_length / 2 - eps2 = z - self.magnet_length / 2 + eps1 = dz + self.magnet_length / 2 + eps2 = dz - self.magnet_length / 2 k1 = (eps1**2 + (dr - self.magnet_radius) ** 2) / ( eps1**2 + (dr + self.magnet_radius) ** 2 ) @@ -298,7 +297,7 @@ def ellipiticPi(n, m): ) * (x - self.magnet_origin[0]) ** 2 / dr**2 - - self.mu0_Ms + + self.mu0_Ms * self._Bzr_np( r=dr, Z=dz, @@ -309,7 +308,7 @@ def ellipiticPi(n, m): ep22=ep22, ep32=ep32, ) - * (y - self.magnet_origin[1]) ** 2 + * ((y - self.magnet_origin[1]) ** 2) / dr**3 ) return BZxx @@ -329,7 +328,7 @@ def ellipiticPi(n, m): ) * (x - self.magnet_origin[0]) ** 2 / dr**2 - - self.mu0_Ms + + self.mu0_Ms * self._Bzr_np( r=dr, Z=dz, @@ -340,7 +339,7 @@ def ellipiticPi(n, m): ep22=ep22, ep32=ep32, ) - * (y - self.magnet_origin[1]) ** 2 + * ((y - self.magnet_origin[1]) ** 2) / dr**3 ) @@ -353,5 +352,6 @@ def _Bz_np(self, r, Z, ep11, ep21, ep31, ep12, ep22, ep32): def _Bzr_np(self, r, Z, ep11, ep21, ep31, ep12, ep22, ep32): return self.magnet_radius*(-(-self.magnet_length/2 + Z)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) - (-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + (-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (ep32*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - (-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/np.sqrt((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (self.magnet_length/2 + Z)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) + (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + (-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (ep31*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - (-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/np.sqrt((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(np.pi*(self.magnet_radius + r)) - self.magnet_radius*(-(-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/np.sqrt((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/np.sqrt((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(np.pi*(self.magnet_radius + r)**2) + def _Bzrr_np(self, r, Z, ep11, ep21, ep31, ep12, ep22, ep32): return self.magnet_radius*(-(-self.magnet_length/2 + Z)*(-3*self.magnet_radius - 3*r)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(5/2) - 2*(-self.magnet_length/2 + Z)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + (-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (ep32*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - (-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) + (-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) - (-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**3) - (-self.magnet_radius + r)*(-ep12 + ep32)*(-4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2/(self.magnet_radius + r)**2)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - 2*(-self.magnet_radius + r)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(2*self.magnet_radius - 2*r)*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2) - (2*self.magnet_radius + 2*r)*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-ep12*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - ep12*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)**2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep22*(2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2 - ep22*(2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) - (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2 - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep12*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep32*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep32*((-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) + ((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)*(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + ((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))*(2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2) - (self.magnet_radius + r)**2*(4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 - 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 - 2/(self.magnet_radius + r)**2)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (2*self.magnet_radius + 2*r)*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) + 2*(self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**3*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + 2*(-self.magnet_radius + r)*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) + 2*(-self.magnet_radius + r)*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - 2*(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)**3*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**3 - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*(-4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - 2*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep32*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (-4*ep32*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2*ep32/(self.magnet_radius + r)**2 + 2*(-2*self.magnet_radius + 2*r)*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 + (-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep22*(2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2 - ep22*(2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) - (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2 - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep12*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep32*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep32*((-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) + ((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)*(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + ((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))*(2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2) - (self.magnet_radius + r)**2*(4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 - 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 - 2/(self.magnet_radius + r)**2)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (2*self.magnet_radius + 2*r)*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) + 2*(self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**3*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**3 - (2*self.magnet_radius - 2*r)*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2) - (2*self.magnet_radius + 2*r)*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-ep12*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - ep12*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)**2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - 2*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - 2*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + 2*(-ep12 + ep32)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/np.sqrt((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (self.magnet_length/2 + Z)*(-3*self.magnet_radius - 3*r)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(5/2) + 2*(self.magnet_length/2 + Z)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + (-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (ep31*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - (-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) - (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) + (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**3) - (-self.magnet_radius + r)*(-ep11 + ep31)*(-4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2/(self.magnet_radius + r)**2)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - 2*(-self.magnet_radius + r)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(2*self.magnet_radius - 2*r)*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2) - (2*self.magnet_radius + 2*r)*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-ep11*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - ep11*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)**2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep21*(2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2 - ep21*(2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) - (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2 - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep11*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep31*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep31*((-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) + ((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)*(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + ((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))*(2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2) - (self.magnet_radius + r)**2*(4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 - 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 - 2/(self.magnet_radius + r)**2)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (2*self.magnet_radius + 2*r)*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) + 2*(self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**3*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + 2*(-self.magnet_radius + r)*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) + 2*(-self.magnet_radius + r)*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - 2*(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)**3*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**3 - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*(-4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - 2*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep31*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (-4*ep31*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2*ep31/(self.magnet_radius + r)**2 + 2*(-2*self.magnet_radius + 2*r)*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 + (-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep21*(2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2 - ep21*(2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) - (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2 - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep11*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep31*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep31*((-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) + ((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)*(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + ((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))*(2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2) - (self.magnet_radius + r)**2*(4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 - 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 - 2/(self.magnet_radius + r)**2)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (2*self.magnet_radius + 2*r)*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) + 2*(self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**3*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**3 - (2*self.magnet_radius - 2*r)*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2) - (2*self.magnet_radius + 2*r)*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-ep11*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - ep11*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)**2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - 2*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - 2*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + 2*(-ep11 + ep31)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/np.sqrt((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(np.pi*(self.magnet_radius + r)) - 2*self.magnet_radius*(-(-self.magnet_length/2 + Z)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) - (-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + (-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (ep32*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - (-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/np.sqrt((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (self.magnet_length/2 + Z)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) + (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + (-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (ep31*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - (-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/np.sqrt((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(np.pi*(self.magnet_radius + r)**2) + 2*self.magnet_radius*(-(-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/np.sqrt((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/np.sqrt((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(np.pi*(self.magnet_radius + r)**3) \ No newline at end of file diff --git a/mrfmsim/component/magnet_cylinder_approx.py b/mrfmsim/component/magnet_cylinder_approx.py new file mode 100644 index 0000000..87177f4 --- /dev/null +++ b/mrfmsim/component/magnet_cylinder_approx.py @@ -0,0 +1,568 @@ +import numpy as np +import numba as nb +from dataclasses import dataclass, field +from mrfmsim.component import ComponentBase + + +@dataclass +class CylinderMagnetApproxByRectangularMagnet(ComponentBase): + """Cylinder magnet object with its Bz, Bzx, Bzxx calculations. + + :param float radius: cylinder magnet radius [nm] + :param float length: cylinder magnet length [nm] + :param tuple origin: the position of the magnet origin (x, y, z) + :param float mu0_Ms: permeability of free space [H/m] + """ + + magnet_radius: float = field(metadata={"unit": "nm", "format": ".1f"}) + magnet_length: float = field(metadata={"unit": "nm", "format": ".1f"}) + magnet_origin: tuple[float, float, float] = field( + metadata={"unit": "nm", "format": ".1f"} + ) + mu0_Ms: float = field(metadata={"unit": "mT"}) + + def __post_init__(self): + d = self.magnet_radius / 10 + + self._range = np.array( + [ + [ + self.magnet_origin[0] - 3 * d, + self.magnet_origin[0] + 3 * d, + self.magnet_origin[1] - 10 * d, + self.magnet_origin[1] + 10 * d, + self.magnet_origin[2] - self.magnet_length / 2, + self.magnet_origin[2] + self.magnet_length / 2, + ], + [ + self.magnet_origin[0] - 5 * d, + self.magnet_origin[0] - 3 * d, + self.magnet_origin[1] - 9 * d, + self.magnet_origin[1] + 9 * d, + self.magnet_origin[2] - self.magnet_length / 2, + self.magnet_origin[2] + self.magnet_length / 2, + ], + [ + self.magnet_origin[0] + 3 * d, + self.magnet_origin[0] + 5 * d, + self.magnet_origin[1] - 9 * d, + self.magnet_origin[1] + 9 * d, + self.magnet_origin[2] - self.magnet_length / 2, + self.magnet_origin[2] + self.magnet_length / 2, + ], + [ + self.magnet_origin[0] - 7 * d, + self.magnet_origin[0] - 5 * d, + self.magnet_origin[1] - 8 * d, + self.magnet_origin[1] + 8 * d, + self.magnet_origin[2] - self.magnet_length / 2, + self.magnet_origin[2] + self.magnet_length / 2, + ], + [ + self.magnet_origin[0] + 5 * d, + self.magnet_origin[0] + 7 * d, + self.magnet_origin[1] - 8 * d, + self.magnet_origin[1] + 8 * d, + self.magnet_origin[2] - self.magnet_length / 2, + self.magnet_origin[2] + self.magnet_length / 2, + ], + [ + self.magnet_origin[0] - 8 * d, + self.magnet_origin[0] - 7 * d, + self.magnet_origin[1] - 7 * d, + self.magnet_origin[1] + 7 * d, + self.magnet_origin[2] - self.magnet_length / 2, + self.magnet_origin[2] + self.magnet_length / 2, + ], + [ + self.magnet_origin[0] + 7 * d, + self.magnet_origin[0] + 8 * d, + self.magnet_origin[1] - 7 * d, + self.magnet_origin[1] + 7 * d, + self.magnet_origin[2] - self.magnet_length / 2, + self.magnet_origin[2] + self.magnet_length / 2, + ], + [ + self.magnet_origin[0] - 9 * d, + self.magnet_origin[0] - 8 * d, + self.magnet_origin[1] - 5 * d, + self.magnet_origin[1] + 5 * d, + self.magnet_origin[2] - self.magnet_length / 2, + self.magnet_origin[2] + self.magnet_length / 2, + ], + [ + self.magnet_origin[0] + 8 * d, + self.magnet_origin[0] + 9 * d, + self.magnet_origin[1] - 5 * d, + self.magnet_origin[1] + 5 * d, + self.magnet_origin[2] - self.magnet_length / 2, + self.magnet_origin[2] + self.magnet_length / 2, + ], + [ + self.magnet_origin[0] - 10 * d, + self.magnet_origin[0] - 9 * d, + self.magnet_origin[1] - 3 * d, + self.magnet_origin[1] + 3 * d, + self.magnet_origin[2] - self.magnet_length / 2, + self.magnet_origin[2] + self.magnet_length / 2, + ], + [ + self.magnet_origin[0] + 9 * d, + self.magnet_origin[0] + 10 * d, + self.magnet_origin[1] - 3 * d, + self.magnet_origin[1] + 3 * d, + self.magnet_origin[2] - self.magnet_length / 2, + self.magnet_origin[2] + self.magnet_length / 2, + ], + ] + ) + self._pre_term = self.mu0_Ms / (4 * np.pi) + + def Bz_method(self, x, y, z): + r"""Calculate magnetic field :math:`B_z` [mT]. + + Approxing Cylinder Magnet by 11 Rectangular Magnet. When viewed from the + vertical direction, we are using a row of rectangles to approximate a circle, + these rectangular blocks are arranged side by side, with the following lengths + and widths: + + (6,1)(10,1)(14,1)(16,2)(18,2)(20,6)(18,2)(16,2)(14,1)(10,1)(6,1) + + This is arroximation for a circle with a diameter of 20, these shapes if found by + Minecraft community.The magnetic field is given by the sum of the magnetic fields + of these 11 rectangles. + + + The magnetic field of RectangularMagnet is calculated following Ravaud2009. + Using the Coulombian model, assuming a uniform magnetization throughout + the volume of the magnet and modeling each face of the magnet as a + layer of continuous current density. The total field is found by + summing over the faces. + The magnetic field is given by: + + .. math:: + B_z = \dfrac{\mu_0 M_s}{4\pi} \sum_{i=1}^{2} + \sum_{j=1}^2 \sum_{k=1}^2(-1)^{i+j+k} + arctan \left( \dfrac{(x - x_i)(y - y_i))}{(z - z_k)R} \right) + + Here :math:`(x,y,z)` are the coordinates for the location at which we + want to know the field; + The magnet spans from x1 to x2 in the ``x``-direction, + y1 to y2 in the ``y``-direction, and z1 to z2 in + the ``z``-direction; + + .. math:: + R = \sqrt{(x - x_i)^2 + (y - y_j)^2 + (z - z_k)^2} + + where :math:`\mu_0 M_s` is the magnet's saturation magnetization in mT. + + **Reference**: + Ravaud, R. and Lemarquand, G. "Magnetic field produced by a + parallelepipedic magnet of various and uniform polarization" , + *PIER*, **2009**, *98*, 207-219 + [`10.2528/PIER09091704 `__]. + + - set the magnet up so that the x and y dimensions are centered about + the zero point. + - The translation in z should shift the tip of the magnet in the + z-direction to be the given distance from the surface. + + :param float x: x coordinate of sample grid [nm] + :param float y: y coordinate of sample grid [nm] + :param float z: z coordinate of sample grid [nm] + """ + dx11, dx12 = x - self._range[0][0], x - self._range[0][1] + dy11, dy12 = y - self._range[0][2], y - self._range[0][3] + dz11, dz12 = z - self._range[0][4], z - self._range[0][5] + + dx21, dx22 = x - self._range[1][0], x - self._range[1][1] + dy21, dy22 = y - self._range[1][2], y - self._range[1][3] + dz21, dz22 = z - self._range[1][4], z - self._range[1][5] + + dx31, dx32 = x - self._range[2][0], x - self._range[2][1] + dy31, dy32 = y - self._range[2][2], y - self._range[2][3] + dz31, dz32 = z - self._range[2][4], z - self._range[2][5] + + dx41, dx42 = x - self._range[3][0], x - self._range[3][1] + dy41, dy42 = y - self._range[3][2], y - self._range[3][3] + dz41, dz42 = z - self._range[3][4], z - self._range[3][5] + + dx51, dx52 = x - self._range[4][0], x - self._range[4][1] + dy51, dy52 = y - self._range[4][2], y - self._range[4][3] + dz51, dz52 = z - self._range[4][4], z - self._range[4][5] + + dx61, dx62 = x - self._range[5][0], x - self._range[5][1] + dy61, dy62 = y - self._range[5][2], y - self._range[5][3] + dz61, dz62 = z - self._range[5][4], z - self._range[5][5] + + dx71, dx72 = x - self._range[6][0], x - self._range[6][1] + dy71, dy72 = y - self._range[6][2], y - self._range[6][3] + dz71, dz72 = z - self._range[6][4], z - self._range[6][5] + + dx81, dx82 = x - self._range[7][0], x - self._range[7][1] + dy81, dy82 = y - self._range[7][2], y - self._range[7][3] + dz81, dz82 = z - self._range[7][4], z - self._range[7][5] + + dx91, dx92 = x - self._range[8][0], x - self._range[8][1] + dy91, dy92 = y - self._range[8][2], y - self._range[8][3] + dz91, dz92 = z - self._range[8][4], z - self._range[8][5] + + dx101, dx102 = x - self._range[9][0], x - self._range[9][1] + dy101, dy102 = y - self._range[9][2], y - self._range[9][3] + dz101, dz102 = z - self._range[9][4], z - self._range[9][5] + + dx111, dx112 = x - self._range[10][0], x - self._range[10][1] + dy111, dy112 = y - self._range[10][2], y - self._range[10][3] + dz111, dz112 = z - self._range[10][4], z - self._range[10][5] + + return self._pre_term * ( + self._bz(dx11, dx12, dy11, dy12, dz11, dz12) + + self._bz(dx21, dx22, dy21, dy22, dz21, dz22) + + self._bz(dx31, dx32, dy31, dy32, dz31, dz32) + + self._bz(dx41, dx42, dy41, dy42, dz41, dz42) + + self._bz(dx51, dx52, dy51, dy52, dz51, dz52) + + self._bz(dx61, dx62, dy61, dy62, dz61, dz62) + + self._bz(dx71, dx72, dy71, dy72, dz71, dz72) + + self._bz(dx81, dx82, dy81, dy82, dz81, dz82) + + self._bz(dx91, dx92, dy91, dy92, dz91, dz92) + + self._bz(dx101, dx102, dy101, dy102, dz101, dz102) + + self._bz(dx111, dx112, dy111, dy112, dz111, dz112) + ) + + @staticmethod + @nb.vectorize( + [ + nb.float64( + nb.float64, + nb.float64, + nb.float64, + nb.float64, + nb.float64, + nb.float64, + ) + ], + nopython=True, + target="parallel", + ) + def _bz(dx1, dx2, dy1, dy2, dz1, dz2): + """Calculate the summation term for magnetic field optimized by numba. + + See method bz for the explanation. + :param float dx1, dx2: distance between grid and the one end of magnet + in x direction [nm] + :param float dy1, dy2: distance between grid and the one end of magnet + in y direction [nm] + :param float dz1, dz2: distance between grid and the one end of magnet + in z direction [nm] + """ + + return ( + -np.arctan2(dx1 * dy1, (np.sqrt(dx1**2 + dy1**2 + dz1**2) * dz1)) + + np.arctan2(dx2 * dy1, (np.sqrt(dx2**2 + dy1**2 + dz1**2) * dz1)) + + np.arctan2(dx1 * dy2, (np.sqrt(dx1**2 + dy2**2 + dz1**2) * dz1)) + - np.arctan2(dx2 * dy2, (np.sqrt(dx2**2 + dy2**2 + dz1**2) * dz1)) + + np.arctan2(dx1 * dy1, (np.sqrt(dx1**2 + dy1**2 + dz2**2) * dz2)) + - np.arctan2(dx2 * dy1, (np.sqrt(dx2**2 + dy1**2 + dz2**2) * dz2)) + - np.arctan2(dx1 * dy2, (np.sqrt(dx1**2 + dy2**2 + dz2**2) * dz2)) + + np.arctan2(dx2 * dy2, (np.sqrt(dx2**2 + dy2**2 + dz2**2) * dz2)) + ) + + def Bzx_method(self, x, y, z): + r"""Calculate magnetic field gradient :math:`B_{zx}`. + + Approxing Cylinder Magnet by 11 Rectangular Magnet. When viewed from the + vertical direction, we are using a row of rectangles to approximate a circle, + these rectangular blocks are arranged side by side, with the following lengths + and widths: + + (6,1)(10,1)(14,1)(16,2)(18,2)(20,6)(18,2)(16,2)(14,1)(10,1)(6,1) + + This is arroximation for a circle with a diameter of 20, these shapes if found by + Minecraft community.The magnetic field is given by the sum of the magnetic fields + of these 11 rectangles. + + The magnetic field gradient for RectangularMagnet is: + math:`B_{zx} = \dfrac{\partial{B_z}}{\partial x}` is + given by the following: + + .. math:: + B_{zx} = \dfrac{\mu_0 M_s}{4 \pi} \sum_{i=1}^2 \sum_{j=1}^2 + \sum_{k=1}^2(-1)^{i+j+k} + \left( \dfrac{(y-y_j)(z-z_k)}{ R((x-x_i)^2 + (z-z_k)^2))} + \right) + + As described above, :math:`(x,y,z)` are coordinates for the location + at which we want to know the field gradient; the magnet spans from + x1 to x2 in the ``x``-direction, y1 to y2 in the ``y``-direction, and + from z1 to z2 in the ``z``-direction; + + .. math:: + R = \sqrt{(x - x_i) + (y - y_j) + (z - z_k)} + + :math:`\mu_0 M_s` is the magnet's saturation magnetization in mT. + + :param float x: ``x`` coordinate [nm] + :param float y: ``y`` coordinate [nm] + :param float z: ``z`` coordinate [nm] + """ + + dx11, dx12 = x - self._range[0][0], x - self._range[0][1] + dy11, dy12 = y - self._range[0][2], y - self._range[0][3] + dz11, dz12 = z - self._range[0][4], z - self._range[0][5] + + dx21, dx22 = x - self._range[1][0], x - self._range[1][1] + dy21, dy22 = y - self._range[1][2], y - self._range[1][3] + dz21, dz22 = z - self._range[1][4], z - self._range[1][5] + + dx31, dx32 = x - self._range[2][0], x - self._range[2][1] + dy31, dy32 = y - self._range[2][2], y - self._range[2][3] + dz31, dz32 = z - self._range[2][4], z - self._range[2][5] + + dx41, dx42 = x - self._range[3][0], x - self._range[3][1] + dy41, dy42 = y - self._range[3][2], y - self._range[3][3] + dz41, dz42 = z - self._range[3][4], z - self._range[3][5] + + dx51, dx52 = x - self._range[4][0], x - self._range[4][1] + dy51, dy52 = y - self._range[4][2], y - self._range[4][3] + dz51, dz52 = z - self._range[4][4], z - self._range[4][5] + + dx61, dx62 = x - self._range[5][0], x - self._range[5][1] + dy61, dy62 = y - self._range[5][2], y - self._range[5][3] + dz61, dz62 = z - self._range[5][4], z - self._range[5][5] + + dx71, dx72 = x - self._range[6][0], x - self._range[6][1] + dy71, dy72 = y - self._range[6][2], y - self._range[6][3] + dz71, dz72 = z - self._range[6][4], z - self._range[6][5] + + dx81, dx82 = x - self._range[7][0], x - self._range[7][1] + dy81, dy82 = y - self._range[7][2], y - self._range[7][3] + dz81, dz82 = z - self._range[7][4], z - self._range[7][5] + + dx91, dx92 = x - self._range[8][0], x - self._range[8][1] + dy91, dy92 = y - self._range[8][2], y - self._range[8][3] + dz91, dz92 = z - self._range[8][4], z - self._range[8][5] + + dx101, dx102 = x - self._range[9][0], x - self._range[9][1] + dy101, dy102 = y - self._range[9][2], y - self._range[9][3] + dz101, dz102 = z - self._range[9][4], z - self._range[9][5] + + dx111, dx112 = x - self._range[10][0], x - self._range[10][1] + dy111, dy112 = y - self._range[10][2], y - self._range[10][3] + dz111, dz112 = z - self._range[10][4], z - self._range[10][5] + + return self._pre_term * ( + self._bzx(dx11, dx12, dy11, dy12, dz11, dz12) + + self._bzx(dx21, dx22, dy21, dy22, dz21, dz22) + + self._bzx(dx31, dx32, dy31, dy32, dz31, dz32) + + self._bzx(dx41, dx42, dy41, dy42, dz41, dz42) + + self._bzx(dx51, dx52, dy51, dy52, dz51, dz52) + + self._bzx(dx61, dx62, dy61, dy62, dz61, dz62) + + self._bzx(dx71, dx72, dy71, dy72, dz71, dz72) + + self._bzx(dx81, dx82, dy81, dy82, dz81, dz82) + + self._bzx(dx91, dx92, dy91, dy92, dz91, dz92) + + self._bzx(dx101, dx102, dy101, dy102, dz101, dz102) + + self._bzx(dx111, dx112, dy111, dy112, dz111, dz112) + ) + + @staticmethod + @nb.vectorize( + [ + nb.float64( + nb.float64, + nb.float64, + nb.float64, + nb.float64, + nb.float64, + nb.float64, + ) + ], + nopython=True, + target="parallel", + ) + def _bzx(dx1, dx2, dy1, dy2, dz1, dz2): + """Calculate the summation term for magnetic field gradient. + + Optimized with numba. See method bzx for the explanation. + + :param np.array dx1, dx2: distance between grid and the 2 ends of + magnet in x direction [nm] + :param np.array dy1, dy2: distance between grid and the 2 ends of + magnet in y direction [nm] + :param np.array dz1, dz2: distance between grid and the 2 ends of + magnet in z direction [nm] + """ + + return ( + -dy1 * dz1 / (np.sqrt(dx1**2 + dy1**2 + dz1**2) * (dx1**2 + dz1**2)) + + dy1 * dz1 / (np.sqrt(dx2**2 + dy1**2 + dz1**2) * (dx2**2 + dz1**2)) + + dy2 * dz1 / (np.sqrt(dx1**2 + dy2**2 + dz1**2) * (dx1**2 + dz1**2)) + - dy2 * dz1 / (np.sqrt(dx2**2 + dy2**2 + dz1**2) * (dx2**2 + dz1**2)) + + dy1 * dz2 / (np.sqrt(dx1**2 + dy1**2 + dz2**2) * (dx1**2 + dz2**2)) + - dy1 * dz2 / (np.sqrt(dx2**2 + dy1**2 + dz2**2) * (dx2**2 + dz2**2)) + - dy2 * dz2 / (np.sqrt(dx1**2 + dy2**2 + dz2**2) * (dx1**2 + dz2**2)) + + dy2 * dz2 / (np.sqrt(dx2**2 + dy2**2 + dz2**2) * (dx2**2 + dz2**2)) + ) + + def Bzxx_method(self, x, y, z): + r"""Calculate magnetic field second derivative :math:`B_{zxx}`/ + + Approxing Cylinder Magnet by 11 Rectangular Magnet. When viewed from the + vertical direction, we are using a row of rectangles to approximate a circle, + these rectangular blocks are arranged side by side, with the following lengths + and widths: + + (6,1)(10,1)(14,1)(16,2)(18,2)(20,6)(18,2)(16,2)(14,1)(10,1)(6,1) + + This is arroximation for a circle with a diameter of 20, these shapes if found by + Minecraft community.The magnetic field is given by the sum of the magnetic fields + of these 11 rectangles. + + The magnetic field second derivative for RectangularMagnet is: + :math:`B_{zxx} \equiv \partial^2 B_z / \partial x^2` + [ :math:`\mathrm{mT} \; \mathrm{nm}^{-2}`] + The magnetic field's second derivative is given by the following: + + .. math:: + B_{zxx} = \dfrac{\partial B_z}{\partial z} + = \dfrac{\mu_0 M_s}{4 \pi} \sum_{i=1}^2 + \sum_{j=1}^2 \sum_{k=1}^2(-1)^{i+j+k} + \left( \dfrac{-(x-x_i)(y-y_j)(z-z_k) + (3(x-x_i)^2 +2(y-y_j)^2 + 3(z-z_k)^2)} + {((x-x_i)^2 + (y-y_j)^2 + (z-z_k)^2)^{3/2} + ((x-x_i)^2 + (z-z_k)^2)^2} \right) + + with the variables defined above. + :param float x: ``x`` coordinate [nm] + :param float y: ``y`` coordinate [nm] + :param float z: ``z`` coordinate [nm] + """ + + dx11, dx12 = x - self._range[0][0], x - self._range[0][1] + dy11, dy12 = y - self._range[0][2], y - self._range[0][3] + dz11, dz12 = z - self._range[0][4], z - self._range[0][5] + + dx21, dx22 = x - self._range[1][0], x - self._range[1][1] + dy21, dy22 = y - self._range[1][2], y - self._range[1][3] + dz21, dz22 = z - self._range[1][4], z - self._range[1][5] + + dx31, dx32 = x - self._range[2][0], x - self._range[2][1] + dy31, dy32 = y - self._range[2][2], y - self._range[2][3] + dz31, dz32 = z - self._range[2][4], z - self._range[2][5] + + dx41, dx42 = x - self._range[3][0], x - self._range[3][1] + dy41, dy42 = y - self._range[3][2], y - self._range[3][3] + dz41, dz42 = z - self._range[3][4], z - self._range[3][5] + + dx51, dx52 = x - self._range[4][0], x - self._range[4][1] + dy51, dy52 = y - self._range[4][2], y - self._range[4][3] + dz51, dz52 = z - self._range[4][4], z - self._range[4][5] + + dx61, dx62 = x - self._range[5][0], x - self._range[5][1] + dy61, dy62 = y - self._range[5][2], y - self._range[5][3] + dz61, dz62 = z - self._range[5][4], z - self._range[5][5] + + dx71, dx72 = x - self._range[6][0], x - self._range[6][1] + dy71, dy72 = y - self._range[6][2], y - self._range[6][3] + dz71, dz72 = z - self._range[6][4], z - self._range[6][5] + + dx81, dx82 = x - self._range[7][0], x - self._range[7][1] + dy81, dy82 = y - self._range[7][2], y - self._range[7][3] + dz81, dz82 = z - self._range[7][4], z - self._range[7][5] + + dx91, dx92 = x - self._range[8][0], x - self._range[8][1] + dy91, dy92 = y - self._range[8][2], y - self._range[8][3] + dz91, dz92 = z - self._range[8][4], z - self._range[8][5] + + dx101, dx102 = x - self._range[9][0], x - self._range[9][1] + dy101, dy102 = y - self._range[9][2], y - self._range[9][3] + dz101, dz102 = z - self._range[9][4], z - self._range[9][5] + + dx111, dx112 = x - self._range[10][0], x - self._range[10][1] + dy111, dy112 = y - self._range[10][2], y - self._range[10][3] + dz111, dz112 = z - self._range[10][4], z - self._range[10][5] + + return self._pre_term * ( + self._bzxx(dx11, dx12, dy11, dy12, dz11, dz12) + + self._bzxx(dx21, dx22, dy21, dy22, dz21, dz22) + + self._bzxx(dx31, dx32, dy31, dy32, dz31, dz32) + + self._bzxx(dx41, dx42, dy41, dy42, dz41, dz42) + + self._bzxx(dx51, dx52, dy51, dy52, dz51, dz52) + + self._bzxx(dx61, dx62, dy61, dy62, dz61, dz62) + + self._bzxx(dx71, dx72, dy71, dy72, dz71, dz72) + + self._bzxx(dx81, dx82, dy81, dy82, dz81, dz82) + + self._bzxx(dx91, dx92, dy91, dy92, dz91, dz92) + + self._bzxx(dx101, dx102, dy101, dy102, dz101, dz102) + + self._bzxx(dx111, dx112, dy111, dy112, dz111, dz112) + ) + + @staticmethod + @nb.vectorize( + [ + nb.float64( + nb.float64, + nb.float64, + nb.float64, + nb.float64, + nb.float64, + nb.float64, + ) + ], + nopython=True, + target="parallel", + ) + def _bzxx(dx1, dx2, dy1, dy2, dz1, dz2): + """The summation term for the second derivative of magnetic field. + + Optimized by numba. See bzxx method for the explanation. + :param float dx1, dx2: distance between grid and the one end of magnet + in x direction [nm] + :param float dy1, dy2: distance between grid and the one end of magnet + in y direction [nm] + :param float dz1, dz2: distance between grid and the one end of magnet + in z direction [nm] + """ + + return ( + +dx1 + * dy1 + * dz1 + * (3.0 * dx1**2 + 2.0 * dy1**2 + 3.0 * dz1**2) + / ((dx1**2 + dy1**2 + dz1**2) ** 1.5 * (dx1**2 + dz1**2) ** 2) + - dx2 + * dy1 + * dz1 + * (3.0 * dx2**2 + 2.0 * dy1**2 + 3.0 * dz1**2) + / ((dx2**2 + dy1**2 + dz1**2) ** 1.5 * (dx2**2 + dz1**2) ** 2) + - dx1 + * dy2 + * dz1 + * (3.0 * dx1**2 + 2.0 * dy2**2 + 3.0 * dz1**2) + / ((dx1**2 + dy2**2 + dz1**2) ** 1.5 * (dx1**2 + dz1**2) ** 2) + + dx2 + * dy2 + * dz1 + * (3.0 * dx2**2 + 2.0 * dy2**2 + 3.0 * dz1**2) + / ((dx2**2 + dy2**2 + dz1**2) ** 1.5 * (dx2**2 + dz1**2) ** 2) + - dx1 + * dy1 + * dz2 + * (3.0 * dx1**2 + 2.0 * dy1**2 + 3.0 * dz2**2) + / ((dx1**2 + dy1**2 + dz2**2) ** 1.5 * (dx1**2 + dz2**2) ** 2) + + dx2 + * dy1 + * dz2 + * (3.0 * dx2**2 + 2.0 * dy1**2 + 3.0 * dz2**2) + / ((dx2**2 + dy1**2 + dz2**2) ** 1.5 * (dx2**2 + dz2**2) ** 2) + + dx1 + * dy2 + * dz2 + * (3.0 * dx1**2 + 2.0 * dy2**2 + 3.0 * dz2**2) + / ((dx1**2 + dy2**2 + dz2**2) ** 1.5 * (dx1**2 + dz2**2) ** 2) + - dx2 + * dy2 + * dz2 + * (3.0 * dx2**2 + 2.0 * dy2**2 + 3.0 * dz2**2) + / ((dx2**2 + dy2**2 + dz2**2) ** 1.5 * (dx2**2 + dz2**2) ** 2) + ) + + \ No newline at end of file diff --git a/mrfmsim/component/magnet_cylinder_indirect.py b/mrfmsim/component/magnet_cylinder_indirect.py deleted file mode 100644 index f404ee2..0000000 --- a/mrfmsim/component/magnet_cylinder_indirect.py +++ /dev/null @@ -1,456 +0,0 @@ -import numpy as np -import sympy -from sympy import elliptic_k, elliptic_pi -from scipy.special import elliprf, ellipk, elliprj, ellipe -from dataclasses import dataclass, field -from mrfmsim.component import ComponentBase - - -@dataclass -class CylinderMagnetIndirect(ComponentBase): - """Cylinder magnet object with its Bz, Bzx, Bzxx calculations. - - :param float radius: cylinder magnet radius [nm] !!!There would ba a singularity when x^2+y^2=R^2, so set a small difference to R!!! Also when x^2+y^2=0, B_zxx would run into a singularity, try to avoid this point. - :param float length: cylinder magnet length [nm] - :param tuple origin: the position of the magnet origin (x, y, z) - :param float mu0_Ms: permeability of free space [H/m] - """ - - magnet_radius: float = field(metadata={"unit": "nm", "format": ".1f"}) - magnet_length: float = field(metadata={"unit": "nm", "format": ".1f"}) - magnet_origin: tuple[float, float, float] = field( - metadata={"unit": "nm", "format": ".1f"} - ) - mu0_Ms: float = field(metadata={"unit": "mT"}) - - def __post_init__(self): - r""" - This function is used to calculate the Bz, Bzr, Bzrr of the cylinder magnet using sympy. Due to the complexity of the expression, we use sympy to calculate the expression and then use sympy.lambdify to convert the expression to a numpy function. - first use sympy to calculate the Bz, Bzr, Bzrr,the equation if from paper:https://doi.org/10.1016/j.jmmm.2018.02.003.(https://www.sciencedirect.com/science/article/pii/S0304885317334662), (note that the def of n is different in the paper and the code, so we need to change the def of n in the code). - Also, we use ep11, ep21, ep31, ep12, ep22, ep32 to replace the elliptic_k, elliptic_e, elliptic_pi, to avoid call elliptic_k, elliptic_e, elliptic_pi repeatedly. - - variables: - r: radius of the sample grid - Z: z coordinate of the sample grid - R: radius of the magnet - L: length of the magnet - ep11, ep21, ep31, ep12, ep22, ep32: precomputed elliptic functions - """ - - r, Z, R, L = sympy.symbols("r Z R L") - ep11, ep21, ep31 = sympy.symbols("ep11 ep21 ep31") - ep12, ep22, ep32 = sympy.symbols("ep12 ep22 ep32") - - g = (r - R) / (r + R) - - eps1 = Z + L - eps2 = Z - L - - alpha1 = 1 / sympy.sqrt(eps1**2 + (r + R) ** 2) - alpha2 = 1 / sympy.sqrt(eps2**2 + (r + R) ** 2) - - k1 = (eps1**2 + (r - R) ** 2) / (eps1**2 + (r + R) ** 2) - k2 = (eps2**2 + (r - R) ** 2) / (eps2**2 + (r + R) ** 2) - n = 1 - g**2 - - P21 = -g / (1 - g**2) * (elliptic_pi(n, 1 - k1) - elliptic_k(1 - k1)) - 1 / ( - 1 - g**2 - ) * (g**2 * elliptic_pi(n, 1 - k1) - elliptic_k(1 - k1)) - P22 = -g / (1 - g**2) * (elliptic_pi(n, 1 - k2) - elliptic_k(1 - k2)) - 1 / ( - 1 - g**2 - ) * (g**2 * elliptic_pi(n, 1 - k2) - elliptic_k(1 - k2)) - - Bz = (P21 * alpha1 * eps1 - P22 * eps2 * alpha2) * R / (r + R) / sympy.pi - Bzr = sympy.diff(Bz, r) - Bzrr = sympy.diff(Bzr, r) - - Bz_subs = Bz.subs( - { - sympy.elliptic_k(1 - k1): ep11, - sympy.elliptic_e(1 - k1): ep21, - sympy.elliptic_pi(n, 1 - k1): ep31, - sympy.elliptic_k(1 - k2): ep12, - sympy.elliptic_e(1 - k2): ep22, - sympy.elliptic_pi(n, 1 - k2): ep32, - } - ) - - Bzr_subs = Bzr.subs( - { - sympy.elliptic_k(1 - k1): ep11, - sympy.elliptic_e(1 - k1): ep21, - sympy.elliptic_pi(n, 1 - k1): ep31, - sympy.elliptic_k(1 - k2): ep12, - sympy.elliptic_e(1 - k2): ep22, - sympy.elliptic_pi(n, 1 - k2): ep32, - } - ) - - Bzrr_subs = Bzrr.subs( - { - sympy.elliptic_k(1 - k1): ep11, - sympy.elliptic_e(1 - k1): ep21, - sympy.elliptic_pi(n, 1 - k1): ep31, - sympy.elliptic_k(1 - k2): ep12, - sympy.elliptic_e(1 - k2): ep22, - sympy.elliptic_pi(n, 1 - k2): ep32, - } - ) - - special_functions = {"sqrt": np.sqrt, "pi": np.pi} - - self.Bz_np = sympy.lambdify( - (r, Z, R, L, ep11, ep21, ep31, ep12, ep22, ep32), - Bz_subs, - modules=[special_functions, "numpy"], - ) - self.Bzr_np = sympy.lambdify( - (r, Z, R, L, ep11, ep21, ep31, ep12, ep22, ep32), - Bzr_subs, - modules=[special_functions, "numpy"], - ) - self.Bzrr_np = sympy.lambdify( - (r, Z, R, L, ep11, ep21, ep31, ep12, ep22, ep32), - Bzrr_subs, - modules=[special_functions, "numpy"], - ) - - def Bz_method(self, x, y, z): - r"""Calculate magnetic field :math:`B_z` [mT]. - - The magnetic field is calculated as - - .. math:: - Bz = mu0_Ms * (P21 * alpha1 * eps1 - P22 * eps2 * alpha2) * R / (r + R) / pi - - in which: - eps1 = z + L/2 - eps2 = z - L/2 - k1 = (eps1**2 + (r - R) ** 2) / (eps1**2 + (r + R) ** 2) - k2 = (eps2**2 + (r - R) ** 2) / (eps2**2 + (r + R) ** 2) - g = (r - R) / (r + R) - n = 1 - g**2 - alpha1 = 1 / \sqrt{eps1**2 + (r + R) ** 2} - alpha2 = 1 / \sqrt{eps2**2 + (r + R) ** 2} - P21 = -g / (1 - g**2) * (elliptic_pi(n, 1 - k1) - elliptic_k(1 - k1)) - 1 / (1 - g**2 ) * (g**2 * elliptic_pi(n, 1 - k1) - elliptic_k(1 - k1)) - P22 = -g / (1 - g**2) * (elliptic_pi(n, 1 - k2) - elliptic_k(1 - k2)) - 1 / (1 - g**2 ) * (g**2 * elliptic_pi(n, 1 - k2) - elliptic_k(1 - k2)) - note that: - the def of n (in elliptic integral) is different in the paper and the code, so we need to change the def of n in the code. - - :param float x: x coordinate of sample grid [nm] - :param float y: y coordinate of sample grid [nm] - :param float z: z coordinate of sample grid [nm] - - - Here :math:`(x,y,z)` is the location at which we want to know the field; - :math:`r` is the radius of the magnet; :math:`r**2 = x**2 + y**2`; - :math 'dx = x-x_0' - :math 'dy = y-y_0' - :math 'dz = z-z_0' - distances to the center of the magnet; - :math:`\mu_0 M_s` is the magnetic sphere's saturation - magnetization in mT. - - There is a singularity when x^2+y^2==0, so we need to manually replace B_z with its corresponding algebraic form: - - .. math:: - Bz = \dfrac{\mu0_Ms}{2} * \dfrac{z + L/2}{\sqrt{(z + L/2)**2 + R**2}} - \dfrac{\mu0_Ms}{2} * \dfrac{z - L/2}{\sqrt{(z - L/2)**2 + R**2}} - """ - - def ellipiticPi(n, m): - return elliprf(0.0, 1.0 - m, 1.0) + (n / 3.0) * elliprj( - 0.0, 1.0 - m, 1.0, 1.0 - n - ) - - dr = np.sqrt( - (x - self.magnet_origin[0]) ** 2 + (y - self.magnet_origin[1]) ** 2 - ) - dz = z - self.magnet_origin[2] - L = self.magnet_length / 2 - g = (dr - self.magnet_radius) / (dr + self.magnet_radius) - eps1 = z + L - eps2 = z - L - k1 = (eps1**2 + (dr - self.magnet_radius) ** 2) / ( - eps1**2 + (dr + self.magnet_radius) ** 2 - ) - k2 = (eps2**2 + (dr - self.magnet_radius) ** 2) / ( - eps2**2 + (dr + self.magnet_radius) ** 2 - ) - n = 1 - g**2 - - ep11 = ellipk(1 - k1) - ep21 = ellipe(1 - k1) - ep31 = ellipiticPi(n, 1 - k1) - - ep12 = ellipk(1 - k2) - ep22 = ellipe(1 - k2) - ep32 = ellipiticPi(n, 1 - k2) - - zero_coords = np.argwhere(dr == 0) - - if zero_coords.size > 0: - dr[zero_coords[0][0]][zero_coords[0][1]][zero_coords[0][2]] = np.nan - BZ = self.mu0_Ms * self.Bz_np( - r=dr, - Z=dz, - R=self.magnet_radius, - L=L, - ep11=ep11, - ep21=ep21, - ep31=ep31, - ep12=ep12, - ep22=ep22, - ep32=ep32, - ) - BZ[zero_coords[0][0]][zero_coords[0][1]][:] = ( - self.mu0_Ms - / 2 - * ( - (dz + self.magnet_length / 2) - / np.sqrt( - (dz + self.magnet_length / 2) ** 2 + (self.magnet_radius) ** 2 - ) - - (dz - self.magnet_length / 2) - / np.sqrt( - (dz - self.magnet_length / 2) ** 2 + (self.magnet_radius) ** 2 - ) - ) - ) - return BZ - - else: - return self.mu0_Ms * self.Bz_np( - r=dr, - Z=dz, - R=self.magnet_radius, - L=L, - ep11=ep11, - ep21=ep21, - ep31=ep31, - ep12=ep12, - ep22=ep22, - ep32=ep32, - ) - - def Bzx_method(self, x, y, z): - r"""Calculate magnetic field :math:`B_z` [mT]. - - The magnetic field is calculated as - - .. math: - \dfrac{\partial B_z}{\partial x} = \dfrac{\partial B_z}{\partial r} * \dfrac{\partial r}{\partial x}+\dfrac{\partial B_z}{\partial z} * \dfrac{\partial z}{\partial x} - =\dfrac{\partial B_z}{\partial r} * \dfrac{x}{r} - - :param float x: x coordinate of sample grid [nm] - :param float y: y coordinate of sample grid [nm] - :param float z: z coordinate of sample grid [nm] - - Here :math:`(x,y,z)` is the location at which we want to know the field; - :math:`r` is the radius of the magnet; :math:`r**2 = x**2 + y**2`; - :math 'dx = x-x_0' - :math 'dy = y-y_0' - :math 'dz = z-z_0' - distances to the center of the magnet; - :math:`\mu_0 M_s` is the magnetic sphere's saturation - magnetization in mT. - """ - - def ellipiticPi(n, m): - return elliprf(0.0, 1.0 - m, 1.0) + (n / 3.0) * elliprj( - 0.0, 1.0 - m, 1.0, 1.0 - n - ) - - dr = np.sqrt( - (x - self.magnet_origin[0]) ** 2 + (y - self.magnet_origin[1]) ** 2 - ) - dz = z - self.magnet_origin[2] - zero_coords = np.argwhere(dr == 0) - - L = self.magnet_length / 2 - g = (dr - self.magnet_radius) / (dr + self.magnet_radius) - eps1 = z + L - eps2 = z - L - k1 = (eps1**2 + (dr - self.magnet_radius) ** 2) / ( - eps1**2 + (dr + self.magnet_radius) ** 2 - ) - k2 = (eps2**2 + (dr - self.magnet_radius) ** 2) / ( - eps2**2 + (dr + self.magnet_radius) ** 2 - ) - n = 1 - g**2 - - ep11 = ellipk(1 - k1) - ep21 = ellipe(1 - k1) - ep31 = ellipiticPi(n, 1 - k1) - - ep12 = ellipk(1 - k2) - ep22 = ellipe(1 - k2) - ep32 = ellipiticPi(n, 1 - k2) - - if zero_coords.size > 0: - dr[zero_coords[0][0]][zero_coords[0][1]][zero_coords[0][2]] = np.nan - BZr = ( - self.mu0_Ms - * self.Bzr_np( - r=dr, - Z=dz, - R=self.magnet_radius, - L=L, - ep11=ep11, - ep21=ep21, - ep31=ep31, - ep12=ep12, - ep22=ep22, - ep32=ep32, - ) - * (x - self.magnet_origin[0]) - / dr - ) - BZr[zero_coords[0][0]][zero_coords[0][1]][:] = np.zeros(len(dz)) - return BZr - - else: - return ( - self.mu0_Ms - * self.Bzr_np( - r=dr, - Z=dz, - R=self.magnet_radius, - L=L, - ep11=ep11, - ep21=ep21, - ep31=ep31, - ep12=ep12, - ep22=ep22, - ep32=ep32, - ) - * (x - self.magnet_origin[0]) - / dr - ) - - def Bzxx_method(self, x, y, z): - r"""Calculate magnetic field :math:`B_z` [mT]. - - The magnetic field is calculated as - - .. math: - using sympy directly calculate the derivative of Bzr - - :param float x: x coordinate of sample grid [nm] - :param float y: y coordinate of sample grid [nm] - :param float z: z coordinate of sample grid [nm] - - - Here :math:`(x,y,z)` is the location at which we want to know the field; - :math:`r` is the radius of the magnet; :math:`r**2 = x**2 + y**2`; - :math 'dx = x-x_0' - :math 'dy = y-y_0' - :math 'dz = z-z_0' - distances to the center of the magnet; - :math:`\mu_0 M_s` is the magnetic sphere's saturation - magnetization in mT. - """ - - def ellipiticPi(n, m): - return elliprf(0.0, 1.0 - m, 1.0) + (n / 3.0) * elliprj( - 0.0, 1.0 - m, 1.0, 1.0 - n - ) - - dr = np.sqrt( - (x - self.magnet_origin[0]) ** 2 + (y - self.magnet_origin[1]) ** 2 - ) - dz = z - self.magnet_origin[2] - - zero_coords = np.argwhere(dr == 0) - - L = self.magnet_length / 2 - g = (dr - self.magnet_radius) / (dr + self.magnet_radius) - eps1 = z + L - eps2 = z - L - k1 = (eps1**2 + (dr - self.magnet_radius) ** 2) / ( - eps1**2 + (dr + self.magnet_radius) ** 2 - ) - k2 = (eps2**2 + (dr - self.magnet_radius) ** 2) / ( - eps2**2 + (dr + self.magnet_radius) ** 2 - ) - n = 1 - g**2 - - # then we calculate the ep11, ep21, ep31, ep12, ep22, ep32, We will precompute the numerical values of these elliptic functions and pass them as inputs to the functions to avoid repeatedly calling the elliptic functions and thus reduce runtime. However, this will increase memory usage. - ep11 = ellipk(1 - k1) - ep21 = ellipe(1 - k1) - ep31 = ellipiticPi(n, 1 - k1) - - ep12 = ellipk(1 - k2) - ep22 = ellipe(1 - k2) - ep32 = ellipiticPi(n, 1 - k2) - - if zero_coords.size > 0: - dr[zero_coords[0][0]][zero_coords[0][1]][zero_coords[0][2]] = ( - x[1] - x[0] - ) / 1000 # I still don't have a good way to approximate this point, so I just set a small difference to 0, notice that Bzxx is symmetric. - BZxx = ( - self.mu0_Ms - * self.Bzrr_np( - r=dr, - Z=dz, - R=self.magnet_radius, - L=L, - ep11=ep11, - ep21=ep21, - ep31=ep31, - ep12=ep12, - ep22=ep22, - ep32=ep32, - ) - * (x - self.magnet_origin[0]) ** 2 - / dr**2 - - self.mu0_Ms - * self.Bzr_np( - r=dr, - Z=dz, - R=self.magnet_radius, - L=L, - ep11=ep11, - ep21=ep21, - ep31=ep31, - ep12=ep12, - ep22=ep22, - ep32=ep32, - ) - * (y - self.magnet_origin[1]) ** 2 - / dr**3 - ) - return BZxx - - else: - return ( - self.mu0_Ms - * self.Bzrr_np( - r=dr, - Z=dz, - R=self.magnet_radius, - L=L, - ep11=ep11, - ep21=ep21, - ep31=ep31, - ep12=ep12, - ep22=ep22, - ep32=ep32, - ) - * (x - self.magnet_origin[0]) ** 2 - / dr**2 - - self.mu0_Ms - * self.Bzr_np( - r=dr, - Z=dz, - R=self.magnet_radius, - L=L, - ep11=ep11, - ep21=ep21, - ep31=ep31, - ep12=ep12, - ep22=ep22, - ep32=ep32, - ) - * (y - self.magnet_origin[1]) ** 2 - / dr**3 - ) diff --git a/tests/test_component/test_magnet_cylinder_approx.py b/tests/test_component/test_magnet_cylinder_approx.py new file mode 100644 index 0000000..164532e --- /dev/null +++ b/tests/test_component/test_magnet_cylinder_approx.py @@ -0,0 +1,88 @@ +import pytest +import numpy as np +from mrfmsim.component import CylinderMagnet, CylinderMagnetApproxByRectangularMagnet + + +class TestCylinderMagnet: + def setup_method(self): + self.magnet = CylinderMagnet( + magnet_radius=0.5, magnet_length=10, magnet_origin=[0, 0, 0], mu0_Ms=1 + ) + self.magnet_approx = CylinderMagnetApproxByRectangularMagnet( + magnet_radius=0.5, magnet_length=10, magnet_origin=[0, 0, 0], mu0_Ms=1 + ) + + # test the shape of the magnetic field + def test_Bz_shape(self): + grid = np.ogrid[-1:1:2j, -1:1:5j, -1:1:10j] + Bz = self.magnet_approx.Bz_method(grid[0], grid[1], grid[2]) + assert Bz.shape == (2, 5, 10) + + def test_Bzx_shape(self): + grid = np.ogrid[-1:1:2j, -1:1:5j, -1:1:10j] + Bzx = self.magnet_approx.Bzx_method(grid[0], grid[1], grid[2]) + assert Bzx.shape == (2, 5, 10) + + def test_Bzxx_shape(self): + grid = np.ogrid[-1:1:2j, -1:1:5j, -1:1:10j] + Bzxx = self.magnet_approx.Bzxx_method(grid[0], grid[1], grid[2]) + assert Bzxx.shape == (2, 5, 10) + + # test the symmetry of the magnetic field + def test_Bz_symmetry(self): + Bz1 = self.magnet_approx.Bz_method(1, 2, 6) + Bz2 = self.magnet_approx.Bz_method(-1, 2, 6) + assert np.allclose(Bz1, Bz2) + + def test_Bzx_symmetry(self): + Bzx1 = self.magnet_approx.Bzx_method(1, 2, 6) + Bzx2 = self.magnet_approx.Bzx_method(-1, 2, 6) + assert np.allclose(Bzx1, -Bzx2) # Bzx is antisymmetric + + def test_Bzxx_symmetry(self): + Bzxx1 = self.magnet_approx.Bzxx_method(1, 2, 6) + Bzxx2 = self.magnet_approx.Bzxx_method(-1, 2, 6) + assert np.allclose(Bzxx1, Bzxx2) # Bzxx is symmetric + + # test the value of the magnetic field + def test_Bz_NearField(self): + grid = np.ogrid[-3:3:10j, -3:3:10j, 6:7:2j] + Bz_approx = self.magnet_approx.Bz_method(grid[0], grid[1], grid[2]) + Bz_exact = self.magnet.Bz_method(grid[0], grid[1], grid[2]) + assert np.allclose(Bz_approx, Bz_exact, rtol=1e-3) + + def test_Bzx_NearField(self): + grid = np.ogrid[-3:3:10j, -3:3:10j, 6:7:2j] + Bzx_approx = self.magnet_approx.Bzx_method(grid[0], grid[1], grid[2]) + Bzx_exact = self.magnet.Bzx_method(grid[0], grid[1], grid[2]) + assert np.allclose(Bzx_approx, Bzx_exact, rtol=1e-3) + + def test_Bzxx_NearField(self): + grid = np.ogrid[-3:3:10j, -3:3:10j, 6:7:2j] + Bzxx_approx = self.magnet_approx.Bzxx_method(grid[0], grid[1], grid[2]) + Bzxx_exact = self.magnet.Bzxx_method(grid[0], grid[1], grid[2]) + assert np.allclose(Bzxx_approx, Bzxx_exact, rtol=1e-3) + + def test_Bz_FarField(self): + grid = np.ogrid[-13:-10:10j, -1:2:10j, 6:7:2j] + Bz_approx = self.magnet_approx.Bz_method(grid[0], grid[1], grid[2]) + Bz_exact = self.magnet.Bz_method(grid[0], grid[1], grid[2]) + assert np.allclose(Bz_approx, Bz_exact, atol=1e-4) + + def test_Bzx_FarField(self): + grid = np.ogrid[-13:-10:10j, -1:2:10j, 6:7:2j] + Bzx_approx = self.magnet_approx.Bzx_method(grid[0], grid[1], grid[2]) + Bzx_exact = self.magnet.Bzx_method(grid[0], grid[1], grid[2]) + assert np.allclose(Bzx_approx, Bzx_exact, atol=1e-6) + + def test_Bzxx_FarField(self): + grid = np.ogrid[-13:-10:10j, -1:2:10j, 6:7:2j] + Bzxx_approx = self.magnet_approx.Bzxx_method(grid[0], grid[1], grid[2]) + Bzxx_exact = self.magnet.Bzxx_method(grid[0], grid[1], grid[2]) + assert np.allclose(Bzxx_approx, Bzxx_exact, atol=1e-6) + + + # test the when x is 0, Bzx is 0 + def test_Bzx_when_x_is_0(self): + Bzx = self.magnet_approx.Bzx_method(0, 10, 0) + assert np.allclose(Bzx, 0, atol=1e-10) From ee57879944dfb677244d19f600f6b13a948cdb31 Mon Sep 17 00:00:00 2001 From: SKeeTElor Date: Thu, 8 May 2025 12:55:15 -0400 Subject: [PATCH 12/45] I fixed bug in the polarization function: In the polarization function, the prolarization when x=0(relative to the center of the cylinder) is not nan due to we are calcutating 0/0. We used to think there gonna be all nan, however, it turns out to be incorrecte. So now the function will find the yz slice that has nan and replace it with the average of 2 slices new to it. I also added a test for the polarization function. There is another way to fix it, I calcuate the limit of the polarization function when x->0, but that need Bzxx, maybe I can write a new version in the future. --- mrfmsim/formula/polarization.py | 7 ++++--- tests/test_formula/test_polarization.py | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/mrfmsim/formula/polarization.py b/mrfmsim/formula/polarization.py index bb8ea30..4d423e0 100644 --- a/mrfmsim/formula/polarization.py +++ b/mrfmsim/formula/polarization.py @@ -245,9 +245,10 @@ def rel_dpol_sat_td(Bzx, B1, ext_B_offset, ext_pts, Gamma, T2, tip_v): div = np.divide(atan_omega_f - atan_omega_i, Bzx) # adjust for the center slice of the discontinuous issue - center_index = div.shape[0] // 2 # if the grid is even it should not be a problem - if np.all(np.isnan(div[center_index])): - div[center_index] = (div[center_index + 1] + div[center_index - 1]) / 2 + nan_indices = np.where(np.isnan(div))[0] + if len(nan_indices) > 0: # get the first nan element x index + div[nan_indices[0]] = (div[nan_indices[0] + 1]) + rt = Gamma * B1**2 * np.abs(div) / tip_v dpol = np.exp(-rt) diff --git a/tests/test_formula/test_polarization.py b/tests/test_formula/test_polarization.py index e382463..aadb779 100644 --- a/tests/test_formula/test_polarization.py +++ b/tests/test_formula/test_polarization.py @@ -177,6 +177,21 @@ def test_rel_dpol_sat_td_symmetry(sample_e): ) assert np.array_equal(rpol_a, rpol_b) +def test_rel_dpol_sat_td_NaN(sample_e): + """Test rel_dpol_sat_td will not return Nan when Bzx is 0 and B_offset is symmetric. + """ + Bzx = np.array([1, 0, -1]) + ext_B_offset_a = np.array([2, 0, 0, 0, 2]) + ext_B_offset_b = np.array([0, 2, 2, 2, 0]) + + rpol_a = pol.rel_dpol_sat_td( + Bzx, 1.0, ext_B_offset_a, 1, sample_e.Gamma, sample_e.T2, 2000 + ) + rpol_b = pol.rel_dpol_sat_td( + Bzx, 1.0, ext_B_offset_b, 1, sample_e.Gamma, sample_e.T2, 2000 + ) + assert (not np.isnan(rpol_a)) and (not np.isnan(rpol_b)) + def test_rel_dpol_sat_td_without_td(sample_e): """Test rel_dpol_sat_td completely saturate spins if no td component. From a72c6170ed0860b2af98334c8de9386ad6ec4955 Mon Sep 17 00:00:00 2001 From: SKeeTElor Date: Sat, 7 Jun 2025 17:00:41 -0400 Subject: [PATCH 13/45] Fix a typo in the intriduction part of magnet files --- mrfmsim/component/magnet_cylinder.py | 2 +- mrfmsim/component/magnet_cylinder_approx.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mrfmsim/component/magnet_cylinder.py b/mrfmsim/component/magnet_cylinder.py index d2bf7af..31bc6f4 100644 --- a/mrfmsim/component/magnet_cylinder.py +++ b/mrfmsim/component/magnet_cylinder.py @@ -12,7 +12,7 @@ class CylinderMagnet(ComponentBase): :param float radius: cylinder magnet radius [nm] !!!There would ba a singularity when x^2+y^2=R^2, so set a small difference to R!!! Also when x^2+y^2=0, B_zxx would run into a singularity, try to avoid this point. :param float length: cylinder magnet length [nm] :param tuple origin: the position of the magnet origin (x, y, z) - :param float mu0_Ms: permeability of free space [H/m] + :param float mu0_Ms: saturation magnetization [mT] """ magnet_radius: float = field(metadata={"unit": "nm", "format": ".1f"}) diff --git a/mrfmsim/component/magnet_cylinder_approx.py b/mrfmsim/component/magnet_cylinder_approx.py index 87177f4..a70463d 100644 --- a/mrfmsim/component/magnet_cylinder_approx.py +++ b/mrfmsim/component/magnet_cylinder_approx.py @@ -11,7 +11,7 @@ class CylinderMagnetApproxByRectangularMagnet(ComponentBase): :param float radius: cylinder magnet radius [nm] :param float length: cylinder magnet length [nm] :param tuple origin: the position of the magnet origin (x, y, z) - :param float mu0_Ms: permeability of free space [H/m] + :param float mu0_Ms: saturation magnetization [mT] """ magnet_radius: float = field(metadata={"unit": "nm", "format": ".1f"}) From 9277285504d6434a69986b6e2ae3f11643c8eb23 Mon Sep 17 00:00:00 2001 From: SKeeTElor Date: Sat, 7 Jun 2025 17:36:38 -0400 Subject: [PATCH 14/45] Create cermittd_fast.py --- mrfmsim/experiment/cermittd_fast.py | 70 +++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 mrfmsim/experiment/cermittd_fast.py diff --git a/mrfmsim/experiment/cermittd_fast.py b/mrfmsim/experiment/cermittd_fast.py new file mode 100644 index 0000000..a049200 --- /dev/null +++ b/mrfmsim/experiment/cermittd_fast.py @@ -0,0 +1,70 @@ +from mrfmsim import formula +from mrfmsim import Node, ExperimentGroup +from .stdelements import STANDARD_NODES, STANDARD_COMPONENTS + +node_objects = [ + Node("rel_dpol td_sat", formula.rel_dpol_sat_td, output="rel_dpol"), + Node("rel_dpol small_steps", formula.rel_dpol_sat_td_smallsteps, output="rel_dpol"), + Node("rel_dpol averaged", formula.rel_dpol_multipulse, output="rel_dpol_avg"), + Node( + "spring constant shift td", + formula.neg_sum_of_product, + inputs=["Bzxx", "rel_dpol_avg", "mz_eq", "spin_density", "grid_voxel"], + output="dk_spin", + doc="Calculate dk_spin account for the negative sign in the approximation.", + ), + Node( + "spring constant shift trapz td", + formula.sum_of_product, + inputs=["Bzxx_trapz", "rel_dpol_avg", "mz_eq", "spin_density", "grid_voxel"], + output="dk_spin", + ), +] + +CermitTD_edges = [ + ["grid extended", "Bz extended"], + ["Bz extended", "B_tot extended"], + ["B_tot extended", ["B_tot sliced", "B_offset extended"]], + ["B_tot sliced", "mz_eq"], + [["B_offset extended", "Bzx", "x_0p window pts"], "rel_dpol td_sat"], + ["rel_dpol td_sat", "rel_dpol averaged"], + [["mz_eq", "Bzxx", "rel_dpol averaged"], "spring constant shift td"], + ["spring constant shift td", "frequency shift"], +] + +CermitTDSmallTip_edges = [ + ["grid extended", ["Bz extended", "Bzx extended"]], + ["Bz extended", "B_tot extended"], + ["B_tot extended", ["B_tot sliced", "B_offset extended"]], + ["B_tot sliced", "mz_eq"], + [["B_offset extended", "Bzx extended", "x_0p window pts"], "rel_dpol small_steps"], + ["rel_dpol small_steps", "rel_dpol averaged"], + [["mz_eq", "Bzxx trapz", "rel_dpol averaged"], "spring constant shift trapz td"], + ["spring constant shift trapz td", "frequency shift"], +] + +experiment_recipes = { + "CermitTD": { + "grouped_edges": CermitTD_edges, + "doc": "Time-dependent CERMIT experiment for a large tip.", + }, + "CermitTDSmallTip": { + "grouped_edges": CermitTDSmallTip_edges, + "doc": "Time-dependent CERMIT experiment for a small tip.", + }, +} + +docstring = """\ +Simulates a Cornell-style frequency shift magnetic +resonance force microscope experiment considering the time-dependent +nature of the saturation, averaged over multiple pulses and with +small-step approximation. +""" + +CermitTDGroup = ExperimentGroup( + name="CermitTDGroup", + node_objects=list(STANDARD_NODES) + node_objects, + experiment_recipes=experiment_recipes, + experiment_defaults={"components": STANDARD_COMPONENTS}, + doc=docstring, +) From cb6b3d47b52f2cc4e1fbd2eedd0e9c2bc91e8706 Mon Sep 17 00:00:00 2001 From: SKeeTElor Date: Tue, 24 Jun 2025 17:36:59 -0400 Subject: [PATCH 15/45] Add notes for the test cases of CylinderMagnet and CylinderMagnetApproxByRectangularMagnet --- mrfmsim/experiment/cermittd_fast.py | 13 +++-- mrfmsim/formula/polarization.py | 37 ++++++++++++++ tests/test_component/test_magnet_cylinder.py | 48 +++++++++++++++++-- .../test_magnet_cylinder_approx.py | 39 +++++++++++++++ 4 files changed, 127 insertions(+), 10 deletions(-) diff --git a/mrfmsim/experiment/cermittd_fast.py b/mrfmsim/experiment/cermittd_fast.py index a049200..f4f4833 100644 --- a/mrfmsim/experiment/cermittd_fast.py +++ b/mrfmsim/experiment/cermittd_fast.py @@ -3,21 +3,20 @@ from .stdelements import STANDARD_NODES, STANDARD_COMPONENTS node_objects = [ - Node("rel_dpol td_sat", formula.rel_dpol_sat_td, output="rel_dpol"), - Node("rel_dpol small_steps", formula.rel_dpol_sat_td_smallsteps, output="rel_dpol"), + Node("rel_dpol td_sat", formula.masked_rel_dpol_sat_td_gridwithpol, output="grid_pol"), Node("rel_dpol averaged", formula.rel_dpol_multipulse, output="rel_dpol_avg"), Node( "spring constant shift td", formula.neg_sum_of_product, - inputs=["Bzxx", "rel_dpol_avg", "mz_eq", "spin_density", "grid_voxel"], + inputs=["Bzxx_pol", "rel_dpol_avg", "mz_eq", "spin_density", "grid_voxel"], output="dk_spin", doc="Calculate dk_spin account for the negative sign in the approximation.", ), Node( - "spring constant shift trapz td", - formula.sum_of_product, - inputs=["Bzxx_trapz", "rel_dpol_avg", "mz_eq", "spin_density", "grid_voxel"], - output="dk_spin", + "Bzxx_pol", + formula.field_func, + inputs=["Bzxx_method", "grid_pol", "h"], + output="Bzxx_pol", ), ] diff --git a/mrfmsim/formula/polarization.py b/mrfmsim/formula/polarization.py index 4d423e0..568504b 100644 --- a/mrfmsim/formula/polarization.py +++ b/mrfmsim/formula/polarization.py @@ -289,3 +289,40 @@ def rel_dpol_multipulse(rel_dpol, T1, dt_pulse): rel_dpol_avg = (np.exp(t_r) - 1) * rel_dpol / t_r / (np.exp(t_r) - pol) return rel_dpol_avg + + +def masked_rel_dpol_sat_td_gridwithpol(Bzx, B1, ext_B_offset, ext_pts, Gamma, T2, grid_array,tip_v,void_mask): + """Relative change in polarization for time-dependent saturation. + + The result is not a steady-state solution because it ignores T1 relaxation. + + Binarizing the polarization with 0 and 1, then retrun the girds that has pol with 1 (pol>0.5). + """ + # ignore division error the Exp takes care of the inf, and nan + np.seterr(divide="ignore", invalid="ignore") + + omega_offset_atan = np.arctan(ext_B_offset * Gamma * T2) + + atan_omega_i = omega_offset_atan[: -ext_pts * 2] + atan_omega_f = omega_offset_atan[ext_pts * 2 :] + + div = np.divide(atan_omega_f - atan_omega_i, Bzx) + + # adjust for the center slice of the discontinuous issue + nan_indices = np.where(np.isnan(div))[0] + if len(nan_indices) > 0: # get the first nan element x index + div[nan_indices[0]] = (div[nan_indices[0] + 1]) + + + rt = Gamma * B1**2 * np.abs(div) / tip_v*void_mask + dpol = np.exp(-rt) + + indices = np.where(dpol < 0.5) + + x = grid_array[0].flatten() + y = grid_array[1].flatten() + z = grid_array[2].flatten() + + grid_pol = np.array([x[indices[0][:]],y[indices[1][:]],z[indices[2][:]]]) + + return grid_pol.T \ No newline at end of file diff --git a/tests/test_component/test_magnet_cylinder.py b/tests/test_component/test_magnet_cylinder.py index 452fcaa..fd99262 100644 --- a/tests/test_component/test_magnet_cylinder.py +++ b/tests/test_component/test_magnet_cylinder.py @@ -3,13 +3,55 @@ from mrfmsim.component import CylinderMagnet +"""Test CylinderMagnet module in mrfmsim.component. + +CylinderMagnet +------------ + +All sphere magnets are tested using the parameters: +radius = 0.5 nm +length = 10 nm +mu0_Ms = 1 mT +origin = [0, 0, 0] nm + +Bz_method +^^^^^^^^^^ + +1. Test Bz's output has the same shape as the input grid +2. Test Bz's output is symmetric along x-axis +3. Test Bz at poles (1.0, 2.0, 6.0) resulting in Bz value of 0.00391404 mT +4. Test Bz at poles (10.0, 0.0, 0.0) resulting in Bz value of -0.00044788490737216163 mT + +Bzx_method +^^^^^^^^^^ + +1. Test Bzx's output has the same shape as the input grid +2. Test Bzx's output is symmetric along x-axis +3. Test Bzx at poles (1.0, 2.0, 6.0) resulting in Bzx value of -0.00221805 mT +4. Test Bzx at poles (10.0, 0.0, 0.0) resulting in Bzx value of 0.00010754599 mT +5. Test Bzx at poles (0.0, 10.0, 0.0) resulting in Bzx value of 0.0 mT + + +Bzxx_method +^^^^^^^^^^ + +1. Test Bzxx's output has the same shape as the input grid +2. Test Bzxx's output is symmetric along x-axis +3. Test Bzxx at poles (1.0, 2.0, 6.0) resulting in Bzxx value of 0.0031995877 mT +4. Test Bzxx at poles (10.0, 0.0, 0.0) resulting in Bzxx value of -3.22679905171e-05 mT + + +""" + + + class TestCylinderMagnet: def setup_method(self): self.magnet = CylinderMagnet( magnet_radius=0.5, magnet_length=10, magnet_origin=[0, 0, 0], mu0_Ms=1 ) - # test the shape of the magnetic field + # test the shape of the magnetic field to be the same as the input grid def test_Bz_shape(self): grid = np.ogrid[-1:1:2j, -1:1:5j, -1:1:10j] Bz = self.magnet.Bz_method(grid[0], grid[1], grid[2]) @@ -25,7 +67,7 @@ def test_Bzxx_shape(self): Bzxx = self.magnet.Bzxx_method(grid[0], grid[1], grid[2]) assert Bzxx.shape == (2, 5, 10) - # test the symmetry of the magnetic field + # test the symmetry of the magnetic field along x-axis def test_Bz_symmetry(self): Bz1 = self.magnet.Bz_method(1, 2, 6) Bz2 = self.magnet.Bz_method(-1, 2, 6) @@ -41,7 +83,7 @@ def test_Bzxx_symmetry(self): Bzxx2 = self.magnet.Bzxx_method(-1, 2, 6) assert np.allclose(Bzxx1, Bzxx2) # Bzxx is symmetric - # test the value of the magnetic field + # test the value of the magnetic field at poles(1.0, 2.0, 6.0) & (10.0, 0.0, 0.0) def test_Bz_1(self): Bz = self.magnet.Bz_method(1, 2, 6) assert np.allclose(Bz, 0.00391404, atol=1e-5) diff --git a/tests/test_component/test_magnet_cylinder_approx.py b/tests/test_component/test_magnet_cylinder_approx.py index 164532e..f0e3f6c 100644 --- a/tests/test_component/test_magnet_cylinder_approx.py +++ b/tests/test_component/test_magnet_cylinder_approx.py @@ -2,6 +2,45 @@ import numpy as np from mrfmsim.component import CylinderMagnet, CylinderMagnetApproxByRectangularMagnet +"""Test CylinderMagnetApproxByRectangularMagnet module in mrfmsim.component. + +CylinderMagnet & CylinderMagnetApproxByRectangularMagnet +------------ + +All sphere magnets are tested using the parameters: +radius = 0.5 nm +length = 10 nm +mu0_Ms = 1 mT +origin = [0, 0, 0] nm + +Bz_method +^^^^^^^^^^ + +1. Test Bz's output has the same shape as the input grid +2. Test Bz's output is symmetric along x-axis +3. Test Bz in the near field is close to the exact value +4. Test Bz in the far field is close to the exact value + +Bzx_method +^^^^^^^^^^ + +1. Test Bzx's output has the same shape as the input grid +2. Test Bzx's output is symmetric along x-axis +3. Test Bzx in the near field is close to the exact value +4. Test Bzx in the far field is close to the exact value +5. Test Bzx when x is 0, Bzx is 0 + + +Bzxx_method +^^^^^^^^^^ + +1. Test Bzxx's output has the same shape as the input grid +2. Test Bzxx's output is symmetric along x-axis +3. Test Bzxx in the near field is close to the exact value +4. Test Bzxx in the far field is close to the exact value + + +""" class TestCylinderMagnet: def setup_method(self): From df947fd0530c991011dbf42076a29f0f782b6887 Mon Sep 17 00:00:00 2001 From: SKeeTElor Date: Wed, 2 Jul 2025 15:40:12 -0400 Subject: [PATCH 16/45] Fix a bug in the polarization formula: rel_dpol_sat_td. It constantly returns NaN. Initially, I thought this was due to a 0/0 division in the middle of the x-axis. However, this issue can occur anywhere when the tip-sample separation is too small. Now, in this function, it scans over the x-axis, identifies all NaN values, and replaces them with the average of their neighboring values. --- mrfmsim/formula/polarization.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mrfmsim/formula/polarization.py b/mrfmsim/formula/polarization.py index 568504b..0a99287 100644 --- a/mrfmsim/formula/polarization.py +++ b/mrfmsim/formula/polarization.py @@ -246,8 +246,9 @@ def rel_dpol_sat_td(Bzx, B1, ext_B_offset, ext_pts, Gamma, T2, tip_v): # adjust for the center slice of the discontinuous issue nan_indices = np.where(np.isnan(div))[0] - if len(nan_indices) > 0: # get the first nan element x index - div[nan_indices[0]] = (div[nan_indices[0] + 1]) + unique_nan_indices = list(set(nan_indices)) + for i in unique_nan_indices: + div[i] = (div[i + 1]+div[i - 1])/2 rt = Gamma * B1**2 * np.abs(div) / tip_v From bd92447ba718ed38c8984070fc47b2762d06bbf0 Mon Sep 17 00:00:00 2001 From: SKeeTElor Date: Wed, 20 Aug 2025 13:43:39 -0400 Subject: [PATCH 17/45] Add docstring in test file of CylinderMagnet ans CylinderMagnetApproxByRec --- mrfmsim/component/__init__.py | 2 +- mrfmsim/component/magnet_cylinder_approx.py | 2 +- mrfmsim/formula/polarization.py | 1 - tests/test_component/test_magnet_cylinder.py | 13 +++++++++++ .../test_magnet_cylinder_approx.py | 23 +++++++++++++++---- 5 files changed, 33 insertions(+), 8 deletions(-) diff --git a/mrfmsim/component/__init__.py b/mrfmsim/component/__init__.py index 057621e..462e8f9 100644 --- a/mrfmsim/component/__init__.py +++ b/mrfmsim/component/__init__.py @@ -4,4 +4,4 @@ from .grid import Grid from .sample import Sample from .magnet_cylinder import CylinderMagnet -from .magnet_cylinder_approx import CylinderMagnetApproxByRectangularMagnet +from .magnet_cylinder_approx import CylinderMagnetApproxByRect diff --git a/mrfmsim/component/magnet_cylinder_approx.py b/mrfmsim/component/magnet_cylinder_approx.py index a70463d..cad17b1 100644 --- a/mrfmsim/component/magnet_cylinder_approx.py +++ b/mrfmsim/component/magnet_cylinder_approx.py @@ -5,7 +5,7 @@ @dataclass -class CylinderMagnetApproxByRectangularMagnet(ComponentBase): +class CylinderMagnetApproxByRect(ComponentBase): """Cylinder magnet object with its Bz, Bzx, Bzxx calculations. :param float radius: cylinder magnet radius [nm] diff --git a/mrfmsim/formula/polarization.py b/mrfmsim/formula/polarization.py index 0a99287..b36eef8 100644 --- a/mrfmsim/formula/polarization.py +++ b/mrfmsim/formula/polarization.py @@ -250,7 +250,6 @@ def rel_dpol_sat_td(Bzx, B1, ext_B_offset, ext_pts, Gamma, T2, tip_v): for i in unique_nan_indices: div[i] = (div[i + 1]+div[i - 1])/2 - rt = Gamma * B1**2 * np.abs(div) / tip_v dpol = np.exp(-rt) diff --git a/tests/test_component/test_magnet_cylinder.py b/tests/test_component/test_magnet_cylinder.py index fd99262..d456cd2 100644 --- a/tests/test_component/test_magnet_cylinder.py +++ b/tests/test_component/test_magnet_cylinder.py @@ -53,62 +53,75 @@ def setup_method(self): # test the shape of the magnetic field to be the same as the input grid def test_Bz_shape(self): + '''Test the shape of the magnetic field Bz to be the same as the input grid''' grid = np.ogrid[-1:1:2j, -1:1:5j, -1:1:10j] Bz = self.magnet.Bz_method(grid[0], grid[1], grid[2]) assert Bz.shape == (2, 5, 10) def test_Bzx_shape(self): + '''Test the shape of the magnetic field Bzx to be the same as the input grid''' grid = np.ogrid[-1:1:2j, -1:1:5j, -1:1:10j] Bzx = self.magnet.Bzx_method(grid[0], grid[1], grid[2]) assert Bzx.shape == (2, 5, 10) def test_Bzxx_shape(self): + '''Test the shape of the magnetic field Bzxx to be the same as the input grid''' grid = np.ogrid[-1:1:2j, -1:1:5j, -1:1:10j] Bzxx = self.magnet.Bzxx_method(grid[0], grid[1], grid[2]) assert Bzxx.shape == (2, 5, 10) # test the symmetry of the magnetic field along x-axis def test_Bz_symmetry(self): + '''Test the symmetry of the magnetic field Bz along x-axis''' Bz1 = self.magnet.Bz_method(1, 2, 6) Bz2 = self.magnet.Bz_method(-1, 2, 6) assert np.allclose(Bz1, Bz2) def test_Bzx_symmetry(self): + '''Test the symmetry of the magnetic field Bzx along x-axis''' Bzx1 = self.magnet.Bzx_method(1, 2, 6) Bzx2 = self.magnet.Bzx_method(-1, 2, 6) assert np.allclose(Bzx1, -Bzx2) # Bzx is antisymmetric def test_Bzxx_symmetry(self): + '''Test the symmetry of the magnetic field Bzxx along x-axis''' Bzxx1 = self.magnet.Bzxx_method(1, 2, 6) Bzxx2 = self.magnet.Bzxx_method(-1, 2, 6) assert np.allclose(Bzxx1, Bzxx2) # Bzxx is symmetric # test the value of the magnetic field at poles(1.0, 2.0, 6.0) & (10.0, 0.0, 0.0) def test_Bz_1(self): + '''Test the magnetic field Bz at near field''' Bz = self.magnet.Bz_method(1, 2, 6) assert np.allclose(Bz, 0.00391404, atol=1e-5) def test_Bzx_1(self): + '''Test the magnetic field Bzx at near field''' Bzx = self.magnet.Bzx_method(1, 2, 6) assert np.allclose(Bzx, -0.00221805, atol=1e-5) def test_Bzxx_1(self): + '''Test the magnetic field Bzxx at near field''' Bzxx = self.magnet.Bzxx_method(1, 2, 6) assert np.allclose(Bzxx, 0.0031995877, atol=1e-5) def test_Bz_2(self): + '''Test the magnetic field Bz at far field''' Bz = self.magnet.Bz_method(10, 0, 0) assert np.allclose(Bz, -0.00044788490737216163, atol=1e-5) def test_Bzx_2(self): + '''Test the magnetic field Bzx at far field''' Bzx = self.magnet.Bzx_method(10, 0, 0) assert np.allclose(Bzx, 0.00010754599, atol=1e-5) def test_Bzxx_2(self): + '''Test the magnetic field Bzxx at far field''' Bzxx = self.magnet.Bzxx_method(10, 0, 0) assert np.allclose(Bzxx, -3.22679905171e-05, atol=1e-5) # test the when x is 0, Bzx is 0 def test_Bzx_when_x_is_0(self): + '''Test the magnetic field Bzx when x is 0''' Bzx = self.magnet.Bzx_method(0, 10, 0) assert np.allclose(Bzx, 0, atol=1e-10) diff --git a/tests/test_component/test_magnet_cylinder_approx.py b/tests/test_component/test_magnet_cylinder_approx.py index f0e3f6c..449c203 100644 --- a/tests/test_component/test_magnet_cylinder_approx.py +++ b/tests/test_component/test_magnet_cylinder_approx.py @@ -1,10 +1,10 @@ import pytest import numpy as np -from mrfmsim.component import CylinderMagnet, CylinderMagnetApproxByRectangularMagnet +from mrfmsim.component import CylinderMagnet, CylinderMagnetApproxByRect -"""Test CylinderMagnetApproxByRectangularMagnet module in mrfmsim.component. +"""Test CylinderMagnetApproxByRect module in mrfmsim.component. -CylinderMagnet & CylinderMagnetApproxByRectangularMagnet +CylinderMagnet & CylinderMagnetApproxByRect ------------ All sphere magnets are tested using the parameters: @@ -47,74 +47,86 @@ def setup_method(self): self.magnet = CylinderMagnet( magnet_radius=0.5, magnet_length=10, magnet_origin=[0, 0, 0], mu0_Ms=1 ) - self.magnet_approx = CylinderMagnetApproxByRectangularMagnet( + self.magnet_approx = CylinderMagnetApproxByRect( magnet_radius=0.5, magnet_length=10, magnet_origin=[0, 0, 0], mu0_Ms=1 ) # test the shape of the magnetic field def test_Bz_shape(self): + '''Test the shape of the magnetic field Bz to be the same as the input grid''' grid = np.ogrid[-1:1:2j, -1:1:5j, -1:1:10j] Bz = self.magnet_approx.Bz_method(grid[0], grid[1], grid[2]) assert Bz.shape == (2, 5, 10) def test_Bzx_shape(self): + '''Test the shape of the magnetic field Bzx to be the same as the input grid''' grid = np.ogrid[-1:1:2j, -1:1:5j, -1:1:10j] Bzx = self.magnet_approx.Bzx_method(grid[0], grid[1], grid[2]) assert Bzx.shape == (2, 5, 10) def test_Bzxx_shape(self): + '''Test the shape of the magnetic field Bzxx to be the same as the input grid''' grid = np.ogrid[-1:1:2j, -1:1:5j, -1:1:10j] Bzxx = self.magnet_approx.Bzxx_method(grid[0], grid[1], grid[2]) assert Bzxx.shape == (2, 5, 10) # test the symmetry of the magnetic field def test_Bz_symmetry(self): + '''Test the x-axis symmetry of the magnetic field Bz''' Bz1 = self.magnet_approx.Bz_method(1, 2, 6) Bz2 = self.magnet_approx.Bz_method(-1, 2, 6) assert np.allclose(Bz1, Bz2) def test_Bzx_symmetry(self): + '''Test the x-axis antisymmetry of the magnetic field Bzx''' Bzx1 = self.magnet_approx.Bzx_method(1, 2, 6) Bzx2 = self.magnet_approx.Bzx_method(-1, 2, 6) assert np.allclose(Bzx1, -Bzx2) # Bzx is antisymmetric def test_Bzxx_symmetry(self): + '''Test the x-axis symmetry of the magnetic field Bzxx''' Bzxx1 = self.magnet_approx.Bzxx_method(1, 2, 6) Bzxx2 = self.magnet_approx.Bzxx_method(-1, 2, 6) assert np.allclose(Bzxx1, Bzxx2) # Bzxx is symmetric # test the value of the magnetic field def test_Bz_NearField(self): + '''Test the near field of the magnetic field Bz to be close to the exact value''' grid = np.ogrid[-3:3:10j, -3:3:10j, 6:7:2j] Bz_approx = self.magnet_approx.Bz_method(grid[0], grid[1], grid[2]) Bz_exact = self.magnet.Bz_method(grid[0], grid[1], grid[2]) assert np.allclose(Bz_approx, Bz_exact, rtol=1e-3) def test_Bzx_NearField(self): + '''Test the near field of the magnetic field Bzx to be close to the exact value''' grid = np.ogrid[-3:3:10j, -3:3:10j, 6:7:2j] Bzx_approx = self.magnet_approx.Bzx_method(grid[0], grid[1], grid[2]) Bzx_exact = self.magnet.Bzx_method(grid[0], grid[1], grid[2]) assert np.allclose(Bzx_approx, Bzx_exact, rtol=1e-3) def test_Bzxx_NearField(self): + '''Test the near field of the magnetic field Bzxx to be close to the exact value''' grid = np.ogrid[-3:3:10j, -3:3:10j, 6:7:2j] Bzxx_approx = self.magnet_approx.Bzxx_method(grid[0], grid[1], grid[2]) Bzxx_exact = self.magnet.Bzxx_method(grid[0], grid[1], grid[2]) assert np.allclose(Bzxx_approx, Bzxx_exact, rtol=1e-3) def test_Bz_FarField(self): + '''Test the far field of the magnetic field Bz to be close to the exact value''' grid = np.ogrid[-13:-10:10j, -1:2:10j, 6:7:2j] Bz_approx = self.magnet_approx.Bz_method(grid[0], grid[1], grid[2]) Bz_exact = self.magnet.Bz_method(grid[0], grid[1], grid[2]) assert np.allclose(Bz_approx, Bz_exact, atol=1e-4) - def test_Bzx_FarField(self): + def test_Bzx_FarField(self): + '''Test the far field of the magnetic field Bzx to be close to the exact value''' grid = np.ogrid[-13:-10:10j, -1:2:10j, 6:7:2j] Bzx_approx = self.magnet_approx.Bzx_method(grid[0], grid[1], grid[2]) Bzx_exact = self.magnet.Bzx_method(grid[0], grid[1], grid[2]) assert np.allclose(Bzx_approx, Bzx_exact, atol=1e-6) def test_Bzxx_FarField(self): + '''Test the far field of the magnetic field Bzxx to be close to the exact value''' grid = np.ogrid[-13:-10:10j, -1:2:10j, 6:7:2j] Bzxx_approx = self.magnet_approx.Bzxx_method(grid[0], grid[1], grid[2]) Bzxx_exact = self.magnet.Bzxx_method(grid[0], grid[1], grid[2]) @@ -123,5 +135,6 @@ def test_Bzxx_FarField(self): # test the when x is 0, Bzx is 0 def test_Bzx_when_x_is_0(self): + '''Test the magnetic field Bzx when x is 0 to be 0''' Bzx = self.magnet_approx.Bzx_method(0, 10, 0) assert np.allclose(Bzx, 0, atol=1e-10) From 18ecfcbaf6a384a8cf041a3ea475a1c8246f805a Mon Sep 17 00:00:00 2001 From: SKeeTElor Date: Wed, 20 Aug 2025 13:46:07 -0400 Subject: [PATCH 18/45] Add CylinderMagnetApproxByRect to path --- 1.0.0 | 5 ----- docs/setup/magnet.rst | 1 + 2 files changed, 1 insertion(+), 5 deletions(-) delete mode 100644 1.0.0 diff --git a/1.0.0 b/1.0.0 deleted file mode 100644 index a291009..0000000 --- a/1.0.0 +++ /dev/null @@ -1,5 +0,0 @@ -Collecting poetry_core - Downloading poetry_core-2.1.2-py3-none-any.whl.metadata (3.5 kB) -Downloading poetry_core-2.1.2-py3-none-any.whl (332 kB) -Installing collected packages: poetry_core -Successfully installed poetry_core-2.1.2 diff --git a/docs/setup/magnet.rst b/docs/setup/magnet.rst index 7dbcfba..1a0f769 100644 --- a/docs/setup/magnet.rst +++ b/docs/setup/magnet.rst @@ -12,6 +12,7 @@ Currently, the two types of magnets supported are mrfmsim.component.magnet.SphereMagnet mrfmsim.component.magnet.RectangularMagnet + mrfmsim.component.magnet_cylinder_approx.CylinderMagnetApproxByRect Example Usage ------------- From cd3909ee9a95d87e8137e6f48f26450b8299f3b7 Mon Sep 17 00:00:00 2001 From: Peter Sun Date: Thu, 23 Oct 2025 21:12:16 -0400 Subject: [PATCH 19/45] Delete 1.0.0 --- 1.0.0 | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 1.0.0 diff --git a/1.0.0 b/1.0.0 deleted file mode 100644 index a291009..0000000 --- a/1.0.0 +++ /dev/null @@ -1,5 +0,0 @@ -Collecting poetry_core - Downloading poetry_core-2.1.2-py3-none-any.whl.metadata (3.5 kB) -Downloading poetry_core-2.1.2-py3-none-any.whl (332 kB) -Installing collected packages: poetry_core -Successfully installed poetry_core-2.1.2 From d01cac15d9daa49360d2ec4fdd9a76a903cb1b18 Mon Sep 17 00:00:00 2001 From: SKeeTElor Date: Wed, 20 Aug 2025 13:46:07 -0400 Subject: [PATCH 20/45] Add CylinderMagnetApproxByRect to path --- 1.0.0 | 5 ----- docs/setup/magnet.rst | 1 + tests/test_component/test_magnet_cylinder.py | 2 ++ tests/test_component/test_magnet_cylinder_approx.py | 2 ++ 4 files changed, 5 insertions(+), 5 deletions(-) delete mode 100644 1.0.0 diff --git a/1.0.0 b/1.0.0 deleted file mode 100644 index a291009..0000000 --- a/1.0.0 +++ /dev/null @@ -1,5 +0,0 @@ -Collecting poetry_core - Downloading poetry_core-2.1.2-py3-none-any.whl.metadata (3.5 kB) -Downloading poetry_core-2.1.2-py3-none-any.whl (332 kB) -Installing collected packages: poetry_core -Successfully installed poetry_core-2.1.2 diff --git a/docs/setup/magnet.rst b/docs/setup/magnet.rst index 7dbcfba..1a0f769 100644 --- a/docs/setup/magnet.rst +++ b/docs/setup/magnet.rst @@ -12,6 +12,7 @@ Currently, the two types of magnets supported are mrfmsim.component.magnet.SphereMagnet mrfmsim.component.magnet.RectangularMagnet + mrfmsim.component.magnet_cylinder_approx.CylinderMagnetApproxByRect Example Usage ------------- diff --git a/tests/test_component/test_magnet_cylinder.py b/tests/test_component/test_magnet_cylinder.py index d456cd2..1ec7b17 100644 --- a/tests/test_component/test_magnet_cylinder.py +++ b/tests/test_component/test_magnet_cylinder.py @@ -3,8 +3,10 @@ from mrfmsim.component import CylinderMagnet + """Test CylinderMagnet module in mrfmsim.component. + CylinderMagnet ------------ diff --git a/tests/test_component/test_magnet_cylinder_approx.py b/tests/test_component/test_magnet_cylinder_approx.py index 449c203..76b2844 100644 --- a/tests/test_component/test_magnet_cylinder_approx.py +++ b/tests/test_component/test_magnet_cylinder_approx.py @@ -2,8 +2,10 @@ import numpy as np from mrfmsim.component import CylinderMagnet, CylinderMagnetApproxByRect + """Test CylinderMagnetApproxByRect module in mrfmsim.component. + CylinderMagnet & CylinderMagnetApproxByRect ------------ From 2d498029f52709e8efe872b54e225914ed9ef2f0 Mon Sep 17 00:00:00 2001 From: SKeeTElor Date: Thu, 23 Oct 2025 21:28:41 -0400 Subject: [PATCH 21/45] Fromat the docstring of CylinderMagnet --- mrfmsim/component/magnet_cylinder.py | 33 +++++++++++++++++----------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/mrfmsim/component/magnet_cylinder.py b/mrfmsim/component/magnet_cylinder.py index 31bc6f4..0d37004 100644 --- a/mrfmsim/component/magnet_cylinder.py +++ b/mrfmsim/component/magnet_cylinder.py @@ -9,7 +9,9 @@ class CylinderMagnet(ComponentBase): """Cylinder magnet object with its Bz, Bzx, Bzxx calculations. - :param float radius: cylinder magnet radius [nm] !!!There would ba a singularity when x^2+y^2=R^2, so set a small difference to R!!! Also when x^2+y^2=0, B_zxx would run into a singularity, try to avoid this point. + :param float radius: cylinder magnet radius [nm] !!!There would ba a singularity + when x^2+y^2=R^2, so set a small difference to R! Also when x^2+y^2=0, B_zxx would + run into a singularity, try to avoid this point. :param float length: cylinder magnet length [nm] :param tuple origin: the position of the magnet origin (x, y, z) :param float mu0_Ms: saturation magnetization [mT] @@ -22,7 +24,6 @@ class CylinderMagnet(ComponentBase): ) mu0_Ms: float = field(metadata={"unit": "mT"}) - def Bz_method(self, x, y, z): r"""Calculate magnetic field :math:`B_z` [mT]. @@ -40,10 +41,13 @@ def Bz_method(self, x, y, z): n = 1 - g**2 alpha1 = 1 / \sqrt{eps1**2 + (r + R) ** 2} alpha2 = 1 / \sqrt{eps2**2 + (r + R) ** 2} - P21 = -g / (1 - g**2) * (elliptic_pi(n, 1 - k1) - elliptic_k(1 - k1)) - 1 / (1 - g**2 ) * (g**2 * elliptic_pi(n, 1 - k1) - elliptic_k(1 - k1)) - P22 = -g / (1 - g**2) * (elliptic_pi(n, 1 - k2) - elliptic_k(1 - k2)) - 1 / (1 - g**2 ) * (g**2 * elliptic_pi(n, 1 - k2) - elliptic_k(1 - k2)) + P21 = -g / (1 - g**2) * (elliptic_pi(n, 1 - k1) - elliptic_k(1 - k1)) - 1 + / (1 - g**2 ) * (g**2 * elliptic_pi(n, 1 - k1) - elliptic_k(1 - k1)) + P22 = -g / (1 - g**2) * (elliptic_pi(n, 1 - k2) - elliptic_k(1 - k2)) - 1 + / (1 - g**2 ) * (g**2 * elliptic_pi(n, 1 - k2) - elliptic_k(1 - k2)) note that: - the def of n (in elliptic integral) is different in the paper and the code, so we need to change the def of n in the code. + the def of n (in elliptic integral) is different in the paper and the code, + so we need to change the def of n in the code. :param float x: x coordinate of sample grid [nm] :param float y: y coordinate of sample grid [nm] @@ -59,10 +63,12 @@ def Bz_method(self, x, y, z): :math:`\mu_0 M_s` is the magnetic sphere's saturation magnetization in mT. - There is a singularity when x^2+y^2==0, so we need to manually replace B_z with its corresponding algebraic form: + There is a singularity when x^2+y^2==0, so we need to manually replace B_z with + its corresponding algebraic form: .. math:: - Bz = \dfrac{\mu0_Ms}{2} * \dfrac{z + L/2}{\sqrt{(z + L/2)**2 + R**2}} - \dfrac{\mu0_Ms}{2} * \dfrac{z - L/2}{\sqrt{(z - L/2)**2 + R**2}} + Bz = \dfrac{\mu0_Ms}{2} * \dfrac{z + L/2}{\sqrt{(z + L/2)**2 + R**2}} - + \dfrac{\mu0_Ms}{2} * \dfrac{z - L/2}{\sqrt{(z - L/2)**2 + R**2}} """ def ellipiticPi(n, m): @@ -141,7 +147,9 @@ def Bzx_method(self, x, y, z): The magnetic field is calculated as .. math: - \dfrac{\partial B_z}{\partial x} = \dfrac{\partial B_z}{\partial r} * \dfrac{\partial r}{\partial x}+\dfrac{\partial B_z}{\partial z} * \dfrac{\partial z}{\partial x} + \dfrac{\partial B_z}{\partial x} = \dfrac{\partial B_z}{\partial r} * + \dfrac{\partial r}{\partial x}+\dfrac{\partial B_z}{\partial z} * + \dfrac{\partial z}{\partial x} =\dfrac{\partial B_z}{\partial r} * \dfrac{x}{r} :param float x: x coordinate of sample grid [nm] @@ -342,16 +350,15 @@ def ellipiticPi(n, m): * ((y - self.magnet_origin[1]) ** 2) / dr**3 ) - + """_BZ_np,_Bzr_np,_Bzrr_np is terribly long, they are calculated with sympy. """ def _Bz_np(self, r, Z, ep11, ep21, ep31, ep12, ep22, ep32): return self.magnet_radius*(-(-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/np.sqrt((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/np.sqrt((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(np.pi*(self.magnet_radius + r)) - + def _Bzr_np(self, r, Z, ep11, ep21, ep31, ep12, ep22, ep32): return self.magnet_radius*(-(-self.magnet_length/2 + Z)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) - (-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + (-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (ep32*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - (-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/np.sqrt((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (self.magnet_length/2 + Z)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) + (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + (-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (ep31*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - (-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/np.sqrt((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(np.pi*(self.magnet_radius + r)) - self.magnet_radius*(-(-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/np.sqrt((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/np.sqrt((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(np.pi*(self.magnet_radius + r)**2) - - + def _Bzrr_np(self, r, Z, ep11, ep21, ep31, ep12, ep22, ep32): - return self.magnet_radius*(-(-self.magnet_length/2 + Z)*(-3*self.magnet_radius - 3*r)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(5/2) - 2*(-self.magnet_length/2 + Z)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + (-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (ep32*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - (-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) + (-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) - (-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**3) - (-self.magnet_radius + r)*(-ep12 + ep32)*(-4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2/(self.magnet_radius + r)**2)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - 2*(-self.magnet_radius + r)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(2*self.magnet_radius - 2*r)*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2) - (2*self.magnet_radius + 2*r)*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-ep12*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - ep12*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)**2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep22*(2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2 - ep22*(2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) - (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2 - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep12*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep32*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep32*((-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) + ((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)*(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + ((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))*(2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2) - (self.magnet_radius + r)**2*(4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 - 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 - 2/(self.magnet_radius + r)**2)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (2*self.magnet_radius + 2*r)*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) + 2*(self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**3*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + 2*(-self.magnet_radius + r)*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) + 2*(-self.magnet_radius + r)*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - 2*(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)**3*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**3 - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*(-4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - 2*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep32*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (-4*ep32*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2*ep32/(self.magnet_radius + r)**2 + 2*(-2*self.magnet_radius + 2*r)*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 + (-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep22*(2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2 - ep22*(2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) - (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2 - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep12*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep32*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep32*((-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) + ((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)*(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + ((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))*(2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2) - (self.magnet_radius + r)**2*(4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 - 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 - 2/(self.magnet_radius + r)**2)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (2*self.magnet_radius + 2*r)*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) + 2*(self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**3*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**3 - (2*self.magnet_radius - 2*r)*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2) - (2*self.magnet_radius + 2*r)*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-ep12*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - ep12*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)**2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - 2*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - 2*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + 2*(-ep12 + ep32)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/np.sqrt((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (self.magnet_length/2 + Z)*(-3*self.magnet_radius - 3*r)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(5/2) + 2*(self.magnet_length/2 + Z)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + (-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (ep31*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - (-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) - (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) + (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**3) - (-self.magnet_radius + r)*(-ep11 + ep31)*(-4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2/(self.magnet_radius + r)**2)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - 2*(-self.magnet_radius + r)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(2*self.magnet_radius - 2*r)*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2) - (2*self.magnet_radius + 2*r)*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-ep11*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - ep11*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)**2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep21*(2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2 - ep21*(2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) - (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2 - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep11*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep31*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep31*((-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) + ((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)*(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + ((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))*(2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2) - (self.magnet_radius + r)**2*(4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 - 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 - 2/(self.magnet_radius + r)**2)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (2*self.magnet_radius + 2*r)*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) + 2*(self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**3*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + 2*(-self.magnet_radius + r)*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) + 2*(-self.magnet_radius + r)*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - 2*(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)**3*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**3 - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*(-4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - 2*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep31*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (-4*ep31*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2*ep31/(self.magnet_radius + r)**2 + 2*(-2*self.magnet_radius + 2*r)*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 + (-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep21*(2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2 - ep21*(2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) - (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2 - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep11*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep31*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep31*((-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) + ((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)*(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + ((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))*(2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2) - (self.magnet_radius + r)**2*(4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 - 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 - 2/(self.magnet_radius + r)**2)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (2*self.magnet_radius + 2*r)*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) + 2*(self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**3*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**3 - (2*self.magnet_radius - 2*r)*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2) - (2*self.magnet_radius + 2*r)*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-ep11*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - ep11*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)**2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - 2*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - 2*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + 2*(-ep11 + ep31)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/np.sqrt((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(np.pi*(self.magnet_radius + r)) - 2*self.magnet_radius*(-(-self.magnet_length/2 + Z)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) - (-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + (-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (ep32*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - (-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/np.sqrt((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (self.magnet_length/2 + Z)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) + (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + (-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (ep31*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - (-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/np.sqrt((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(np.pi*(self.magnet_radius + r)**2) + 2*self.magnet_radius*(-(-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/np.sqrt((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/np.sqrt((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(np.pi*(self.magnet_radius + r)**3) \ No newline at end of file + return self.magnet_radius*(-(-self.magnet_length/2 + Z)*(-3*self.magnet_radius - 3*r)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(5/2) - 2*(-self.magnet_length/2 + Z)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + (-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (ep32*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - (-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) + (-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) - (-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**3) - (-self.magnet_radius + r)*(-ep12 + ep32)*(-4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2/(self.magnet_radius + r)**2)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - 2*(-self.magnet_radius + r)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(2*self.magnet_radius - 2*r)*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2) - (2*self.magnet_radius + 2*r)*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-ep12*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - ep12*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)**2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep22*(2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2 - ep22*(2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) - (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2 - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep12*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep32*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep32*((-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) + ((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)*(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + ((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))*(2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2) - (self.magnet_radius + r)**2*(4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 - 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 - 2/(self.magnet_radius + r)**2)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (2*self.magnet_radius + 2*r)*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) + 2*(self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**3*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + 2*(-self.magnet_radius + r)*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) + 2*(-self.magnet_radius + r)*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - 2*(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)**3*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**3 - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*(-4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - 2*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep32*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (-4*ep32*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2*ep32/(self.magnet_radius + r)**2 + 2*(-2*self.magnet_radius + 2*r)*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 + (-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep22*(2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2 - ep22*(2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) - (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2 - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep12*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep32*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep32*((-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) + ((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)*(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + ((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))*(2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2) - (self.magnet_radius + r)**2*(4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 - 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 - 2/(self.magnet_radius + r)**2)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (2*self.magnet_radius + 2*r)*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) + 2*(self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**3*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**3 - (2*self.magnet_radius - 2*r)*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2) - (2*self.magnet_radius + 2*r)*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-ep12*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - ep12*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)**2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - 2*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - 2*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + 2*(-ep12 + ep32)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/np.sqrt((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (self.magnet_length/2 + Z)*(-3*self.magnet_radius - 3*r)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(5/2) + 2*(self.magnet_length/2 + Z)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + (-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (ep31*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - (-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) - (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) + (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**3) - (-self.magnet_radius + r)*(-ep11 + ep31)*(-4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2/(self.magnet_radius + r)**2)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - 2*(-self.magnet_radius + r)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(2*self.magnet_radius - 2*r)*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2) - (2*self.magnet_radius + 2*r)*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-ep11*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - ep11*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)**2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep21*(2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2 - ep21*(2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) - (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2 - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep11*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep31*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep31*((-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) + ((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)*(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + ((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))*(2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2) - (self.magnet_radius + r)**2*(4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 - 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 - 2/(self.magnet_radius + r)**2)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (2*self.magnet_radius + 2*r)*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) + 2*(self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**3*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + 2*(-self.magnet_radius + r)*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) + 2*(-self.magnet_radius + r)*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - 2*(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)**3*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**3 - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*(-4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - 2*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep31*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (-4*ep31*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2*ep31/(self.magnet_radius + r)**2 + 2*(-2*self.magnet_radius + 2*r)*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 + (-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep21*(2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2 - ep21*(2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) - (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2 - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep11*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep31*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep31*((-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) + ((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)*(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + ((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))*(2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2) - (self.magnet_radius + r)**2*(4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 - 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 - 2/(self.magnet_radius + r)**2)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (2*self.magnet_radius + 2*r)*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) + 2*(self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**3*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**3 - (2*self.magnet_radius - 2*r)*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2) - (2*self.magnet_radius + 2*r)*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-ep11*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - ep11*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)**2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - 2*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - 2*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + 2*(-ep11 + ep31)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/np.sqrt((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(np.pi*(self.magnet_radius + r)) - 2*self.magnet_radius*(-(-self.magnet_length/2 + Z)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) - (-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + (-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (ep32*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - (-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/np.sqrt((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (self.magnet_length/2 + Z)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) + (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + (-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (ep31*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - (-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/np.sqrt((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(np.pi*(self.magnet_radius + r)**2) + 2*self.magnet_radius*(-(-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/np.sqrt((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/np.sqrt((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(np.pi*(self.magnet_radius + r)**3) From 31d807cbb75e73066a3c9de8305b97b2f7842802 Mon Sep 17 00:00:00 2001 From: SKeeTElor Date: Thu, 23 Oct 2025 21:44:40 -0400 Subject: [PATCH 22/45] Delete CylinderMagnet CylinderMagnet.py use analytical solution to calculate the magnetic field, which is too long to calculate, so we decide to just use the approximate method. --- mrfmsim/component/__init__.py | 1 - mrfmsim/component/magnet_cylinder.py | 364 ------------------- tests/test_component/test_magnet_cylinder.py | 129 ------- 3 files changed, 494 deletions(-) delete mode 100644 mrfmsim/component/magnet_cylinder.py delete mode 100644 tests/test_component/test_magnet_cylinder.py diff --git a/mrfmsim/component/__init__.py b/mrfmsim/component/__init__.py index 462e8f9..a4e8f8e 100644 --- a/mrfmsim/component/__init__.py +++ b/mrfmsim/component/__init__.py @@ -3,5 +3,4 @@ from .cantilever import Cantilever from .grid import Grid from .sample import Sample -from .magnet_cylinder import CylinderMagnet from .magnet_cylinder_approx import CylinderMagnetApproxByRect diff --git a/mrfmsim/component/magnet_cylinder.py b/mrfmsim/component/magnet_cylinder.py deleted file mode 100644 index 0d37004..0000000 --- a/mrfmsim/component/magnet_cylinder.py +++ /dev/null @@ -1,364 +0,0 @@ -import numpy as np -import numba as nb -from scipy.special import elliprf, ellipk, elliprj, ellipe -from dataclasses import dataclass, field -from mrfmsim.component import ComponentBase - - -@dataclass -class CylinderMagnet(ComponentBase): - """Cylinder magnet object with its Bz, Bzx, Bzxx calculations. - - :param float radius: cylinder magnet radius [nm] !!!There would ba a singularity - when x^2+y^2=R^2, so set a small difference to R! Also when x^2+y^2=0, B_zxx would - run into a singularity, try to avoid this point. - :param float length: cylinder magnet length [nm] - :param tuple origin: the position of the magnet origin (x, y, z) - :param float mu0_Ms: saturation magnetization [mT] - """ - - magnet_radius: float = field(metadata={"unit": "nm", "format": ".1f"}) - magnet_length: float = field(metadata={"unit": "nm", "format": ".1f"}) - magnet_origin: tuple[float, float, float] = field( - metadata={"unit": "nm", "format": ".1f"} - ) - mu0_Ms: float = field(metadata={"unit": "mT"}) - - def Bz_method(self, x, y, z): - r"""Calculate magnetic field :math:`B_z` [mT]. - - The magnetic field is calculated as - - .. math:: - Bz = mu0_Ms * (P21 * alpha1 * eps1 - P22 * eps2 * alpha2) * R / (r + R) / pi - - in which: - eps1 = z + L/2 - eps2 = z - L/2 - k1 = (eps1**2 + (r - R) ** 2) / (eps1**2 + (r + R) ** 2) - k2 = (eps2**2 + (r - R) ** 2) / (eps2**2 + (r + R) ** 2) - g = (r - R) / (r + R) - n = 1 - g**2 - alpha1 = 1 / \sqrt{eps1**2 + (r + R) ** 2} - alpha2 = 1 / \sqrt{eps2**2 + (r + R) ** 2} - P21 = -g / (1 - g**2) * (elliptic_pi(n, 1 - k1) - elliptic_k(1 - k1)) - 1 - / (1 - g**2 ) * (g**2 * elliptic_pi(n, 1 - k1) - elliptic_k(1 - k1)) - P22 = -g / (1 - g**2) * (elliptic_pi(n, 1 - k2) - elliptic_k(1 - k2)) - 1 - / (1 - g**2 ) * (g**2 * elliptic_pi(n, 1 - k2) - elliptic_k(1 - k2)) - note that: - the def of n (in elliptic integral) is different in the paper and the code, - so we need to change the def of n in the code. - - :param float x: x coordinate of sample grid [nm] - :param float y: y coordinate of sample grid [nm] - :param float z: z coordinate of sample grid [nm] - - - Here :math:`(x,y,z)` is the location at which we want to know the field; - :math:`r` is the radius of the magnet; :math:`r**2 = x**2 + y**2`; - :math 'dx = x-x_0' - :math 'dy = y-y_0' - :math 'dz = z-z_0' - distances to the center of the magnet; - :math:`\mu_0 M_s` is the magnetic sphere's saturation - magnetization in mT. - - There is a singularity when x^2+y^2==0, so we need to manually replace B_z with - its corresponding algebraic form: - - .. math:: - Bz = \dfrac{\mu0_Ms}{2} * \dfrac{z + L/2}{\sqrt{(z + L/2)**2 + R**2}} - - \dfrac{\mu0_Ms}{2} * \dfrac{z - L/2}{\sqrt{(z - L/2)**2 + R**2}} - """ - - def ellipiticPi(n, m): - return elliprf(0.0, 1.0 - m, 1.0) + (n / 3.0) * elliprj( - 0.0, 1.0 - m, 1.0, 1.0 - n - ) - - dr = np.sqrt( - (x - self.magnet_origin[0]) ** 2 + (y - self.magnet_origin[1]) ** 2 - ) - dz = z - self.magnet_origin[2] - g = (dr - self.magnet_radius) / (dr + self.magnet_radius) - eps1 = dz + self.magnet_length / 2 - eps2 = dz - self.magnet_length / 2 - k1 = (eps1**2 + (dr - self.magnet_radius) ** 2) / ( - eps1**2 + (dr + self.magnet_radius) ** 2 - ) - k2 = (eps2**2 + (dr - self.magnet_radius) ** 2) / ( - eps2**2 + (dr + self.magnet_radius) ** 2 - ) - n = 1 - g**2 - - ep11 = ellipk(1 - k1) - ep21 = ellipe(1 - k1) - ep31 = ellipiticPi(n, 1 - k1) - - ep12 = ellipk(1 - k2) - ep22 = ellipe(1 - k2) - ep32 = ellipiticPi(n, 1 - k2) - - zero_coords = np.argwhere(dr == 0) - - if zero_coords.size > 0: - dr[zero_coords[0][0]][zero_coords[0][1]][zero_coords[0][2]] = np.nan - BZ = self.mu0_Ms * self._Bz_np( - r=dr, - Z=dz, - ep11=ep11, - ep21=ep21, - ep31=ep31, - ep12=ep12, - ep22=ep22, - ep32=ep32, - ) - BZ[zero_coords[0][0]][zero_coords[0][1]][:] = ( - self.mu0_Ms - / 2 - * ( - (dz + self.magnet_length / 2) - / np.sqrt( - (dz + self.magnet_length / 2) ** 2 + (self.magnet_radius) ** 2 - ) - - (dz - self.magnet_length / 2) - / np.sqrt( - (dz - self.magnet_length / 2) ** 2 + (self.magnet_radius) ** 2 - ) - ) - ) - return BZ - - else: - return self.mu0_Ms * self._Bz_np( - r=dr, - Z=dz, - ep11=ep11, - ep21=ep21, - ep31=ep31, - ep12=ep12, - ep22=ep22, - ep32=ep32, - ) - - def Bzx_method(self, x, y, z): - r"""Calculate magnetic field :math:`B_z` [mT]. - - The magnetic field is calculated as - - .. math: - \dfrac{\partial B_z}{\partial x} = \dfrac{\partial B_z}{\partial r} * - \dfrac{\partial r}{\partial x}+\dfrac{\partial B_z}{\partial z} * - \dfrac{\partial z}{\partial x} - =\dfrac{\partial B_z}{\partial r} * \dfrac{x}{r} - - :param float x: x coordinate of sample grid [nm] - :param float y: y coordinate of sample grid [nm] - :param float z: z coordinate of sample grid [nm] - - Here :math:`(x,y,z)` is the location at which we want to know the field; - :math:`r` is the radius of the magnet; :math:`r**2 = x**2 + y**2`; - :math 'dx = x-x_0' - :math 'dy = y-y_0' - :math 'dz = z-z_0' - distances to the center of the magnet; - :math:`\mu_0 M_s` is the magnetic sphere's saturation - magnetization in mT. - """ - - def ellipiticPi(n, m): - return elliprf(0.0, 1.0 - m, 1.0) + (n / 3.0) * elliprj( - 0.0, 1.0 - m, 1.0, 1.0 - n - ) - - dr = np.sqrt( - (x - self.magnet_origin[0]) ** 2 + (y - self.magnet_origin[1]) ** 2 - ) - dz = z - self.magnet_origin[2] - zero_coords = np.argwhere(dr == 0) - - g = (dr - self.magnet_radius) / (dr + self.magnet_radius) - eps1 = dz + self.magnet_length / 2 - eps2 = dz - self.magnet_length / 2 - k1 = (eps1**2 + (dr - self.magnet_radius) ** 2) / ( - eps1**2 + (dr + self.magnet_radius) ** 2 - ) - k2 = (eps2**2 + (dr - self.magnet_radius) ** 2) / ( - eps2**2 + (dr + self.magnet_radius) ** 2 - ) - n = 1 - g**2 - - ep11 = ellipk(1 - k1) - ep21 = ellipe(1 - k1) - ep31 = ellipiticPi(n, 1 - k1) - - ep12 = ellipk(1 - k2) - ep22 = ellipe(1 - k2) - ep32 = ellipiticPi(n, 1 - k2) - - if zero_coords.size > 0: - dr[zero_coords[0][0]][zero_coords[0][1]][zero_coords[0][2]] = np.nan - BZr = ( - self.mu0_Ms - * self._Bzr_np( - r=dr, - Z=dz, - ep11=ep11, - ep21=ep21, - ep31=ep31, - ep12=ep12, - ep22=ep22, - ep32=ep32, - ) - * (x - self.magnet_origin[0]) - / dr - ) - BZr[zero_coords[0][0]][zero_coords[0][1]][:] = np.zeros(len(dz)) - return BZr - - else: - return ( - self.mu0_Ms - * self._Bzr_np( - r=dr, - Z=dz, - ep11=ep11, - ep21=ep21, - ep31=ep31, - ep12=ep12, - ep22=ep22, - ep32=ep32, - ) - * (x - self.magnet_origin[0]) - / dr - ) - - def Bzxx_method(self, x, y, z): - r"""Calculate magnetic field :math:`B_z` [mT]. - - The magnetic field is calculated as - - .. math: - using sympy directly calculate the derivative of Bzr - - :param float x: x coordinate of sample grid [nm] - :param float y: y coordinate of sample grid [nm] - :param float z: z coordinate of sample grid [nm] - - - Here :math:`(x,y,z)` is the location at which we want to know the field; - :math:`r` is the radius of the magnet; :math:`r**2 = x**2 + y**2`; - :math 'dx = x-x_0' - :math 'dy = y-y_0' - :math 'dz = z-z_0' - distances to the center of the magnet; - :math:`\mu_0 M_s` is the magnetic sphere's saturation - magnetization in mT. - """ - - def ellipiticPi(n, m): - return elliprf(0.0, 1.0 - m, 1.0) + (n / 3.0) * elliprj( - 0.0, 1.0 - m, 1.0, 1.0 - n - ) - - dr = np.sqrt( - (x - self.magnet_origin[0]) ** 2 + (y - self.magnet_origin[1]) ** 2 - ) - dz = z - self.magnet_origin[2] - - zero_coords = np.argwhere(dr == 0) - - g = (dr - self.magnet_radius) / (dr + self.magnet_radius) - eps1 = dz + self.magnet_length / 2 - eps2 = dz - self.magnet_length / 2 - k1 = (eps1**2 + (dr - self.magnet_radius) ** 2) / ( - eps1**2 + (dr + self.magnet_radius) ** 2 - ) - k2 = (eps2**2 + (dr - self.magnet_radius) ** 2) / ( - eps2**2 + (dr + self.magnet_radius) ** 2 - ) - n = 1 - g**2 - - ep11 = ellipk(1 - k1) - ep21 = ellipe(1 - k1) - ep31 = ellipiticPi(n, 1 - k1) - - ep12 = ellipk(1 - k2) - ep22 = ellipe(1 - k2) - ep32 = ellipiticPi(n, 1 - k2) - - if zero_coords.size > 0: - dr[zero_coords[0][0]][zero_coords[0][1]][zero_coords[0][2]] = ( - x[1] - x[0] - ) / 1000 # I still don't have a good way to approximate this point, so I just set a small difference to 0, notice that Bzxx is symmetric. - BZxx = ( - self.mu0_Ms - * self._Bzrr_np( - r=dr, - Z=dz, - ep11=ep11, - ep21=ep21, - ep31=ep31, - ep12=ep12, - ep22=ep22, - ep32=ep32, - ) - * (x - self.magnet_origin[0]) ** 2 - / dr**2 - + self.mu0_Ms - * self._Bzr_np( - r=dr, - Z=dz, - ep11=ep11, - ep21=ep21, - ep31=ep31, - ep12=ep12, - ep22=ep22, - ep32=ep32, - ) - * ((y - self.magnet_origin[1]) ** 2) - / dr**3 - ) - return BZxx - - else: - return ( - self.mu0_Ms - * self._Bzrr_np( - r=dr, - Z=dz, - ep11=ep11, - ep21=ep21, - ep31=ep31, - ep12=ep12, - ep22=ep22, - ep32=ep32, - ) - * (x - self.magnet_origin[0]) ** 2 - / dr**2 - + self.mu0_Ms - * self._Bzr_np( - r=dr, - Z=dz, - ep11=ep11, - ep21=ep21, - ep31=ep31, - ep12=ep12, - ep22=ep22, - ep32=ep32, - ) - * ((y - self.magnet_origin[1]) ** 2) - / dr**3 - ) - - """_BZ_np,_Bzr_np,_Bzrr_np is terribly long, they are calculated with sympy. - """ - - def _Bz_np(self, r, Z, ep11, ep21, ep31, ep12, ep22, ep32): - return self.magnet_radius*(-(-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/np.sqrt((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/np.sqrt((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(np.pi*(self.magnet_radius + r)) - - def _Bzr_np(self, r, Z, ep11, ep21, ep31, ep12, ep22, ep32): - return self.magnet_radius*(-(-self.magnet_length/2 + Z)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) - (-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + (-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (ep32*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - (-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/np.sqrt((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (self.magnet_length/2 + Z)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) + (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + (-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (ep31*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - (-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/np.sqrt((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(np.pi*(self.magnet_radius + r)) - self.magnet_radius*(-(-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/np.sqrt((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/np.sqrt((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(np.pi*(self.magnet_radius + r)**2) - - def _Bzrr_np(self, r, Z, ep11, ep21, ep31, ep12, ep22, ep32): - return self.magnet_radius*(-(-self.magnet_length/2 + Z)*(-3*self.magnet_radius - 3*r)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(5/2) - 2*(-self.magnet_length/2 + Z)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + (-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (ep32*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - (-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) + (-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) - (-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**3) - (-self.magnet_radius + r)*(-ep12 + ep32)*(-4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2/(self.magnet_radius + r)**2)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - 2*(-self.magnet_radius + r)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(2*self.magnet_radius - 2*r)*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2) - (2*self.magnet_radius + 2*r)*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-ep12*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - ep12*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)**2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep22*(2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2 - ep22*(2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) - (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2 - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep12*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep32*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep32*((-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) + ((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)*(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + ((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))*(2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2) - (self.magnet_radius + r)**2*(4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 - 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 - 2/(self.magnet_radius + r)**2)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (2*self.magnet_radius + 2*r)*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) + 2*(self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**3*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + 2*(-self.magnet_radius + r)*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) + 2*(-self.magnet_radius + r)*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - 2*(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)**3*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**3 - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*(-4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - 2*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep32*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (-4*ep32*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2*ep32/(self.magnet_radius + r)**2 + 2*(-2*self.magnet_radius + 2*r)*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 + (-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep22*(2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2 - ep22*(2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) - (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2 - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep12*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep32*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep32*((-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) + ((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)*(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + ((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))*(2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2) - (self.magnet_radius + r)**2*(4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 - 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 - 2/(self.magnet_radius + r)**2)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (2*self.magnet_radius + 2*r)*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) + 2*(self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**3*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**3 - (2*self.magnet_radius - 2*r)*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2) - (2*self.magnet_radius + 2*r)*(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-ep12*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - ep12*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-ep12 + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2))/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(2*(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)**2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - 2*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - 2*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + 2*(-ep12 + ep32)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/np.sqrt((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (self.magnet_length/2 + Z)*(-3*self.magnet_radius - 3*r)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(5/2) + 2*(self.magnet_length/2 + Z)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + (-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (ep31*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - (-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) - (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) + (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**3) - (-self.magnet_radius + r)*(-ep11 + ep31)*(-4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2/(self.magnet_radius + r)**2)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - 2*(-self.magnet_radius + r)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(2*self.magnet_radius - 2*r)*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2) - (2*self.magnet_radius + 2*r)*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-ep11*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - ep11*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)**2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep21*(2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2 - ep21*(2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) - (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2 - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep11*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep31*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep31*((-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) + ((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)*(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + ((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))*(2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2) - (self.magnet_radius + r)**2*(4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 - 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 - 2/(self.magnet_radius + r)**2)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (2*self.magnet_radius + 2*r)*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) + 2*(self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**3*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + 2*(-self.magnet_radius + r)*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) + 2*(-self.magnet_radius + r)*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - 2*(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)**3*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**3 - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*(-4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - 2*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep31*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (-4*ep31*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 + 6*ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 + 2*ep31/(self.magnet_radius + r)**2 + 2*(-2*self.magnet_radius + 2*r)*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 + (-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep21*(2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2 - ep21*(2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) - (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2 - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep11*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep31*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ep31*((-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) + ((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)*(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + ((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))*(2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 2*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 4*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))**2) - (self.magnet_radius + r)**2*(4*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**3 - 6*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**4 - 2/(self.magnet_radius + r)**2)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) - (2*self.magnet_radius + 2*r)*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))) + 2*(self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**3*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - 4*(-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**3 - (2*self.magnet_radius - 2*r)*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)**2) - (2*self.magnet_radius + 2*r)*(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-(-4*self.magnet_radius - 4*r)*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**3 - 2*(-2*self.magnet_radius - 2*r)*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - 2/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)*(-ep11*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - ep11*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (-ep11 + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2))/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*(2*(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 + 2*(-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)**2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - 2*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - 2*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + 2*(-ep11 + ep31)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/np.sqrt((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(np.pi*(self.magnet_radius + r)) - 2*self.magnet_radius*(-(-self.magnet_length/2 + Z)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) - (-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + (-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (ep32*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep22*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep32)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep12*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep22 + ep32*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep12*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep22)*(-(-2*self.magnet_radius - 2*r)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((-self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - (-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/np.sqrt((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (self.magnet_length/2 + Z)*(-self.magnet_radius - r)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**(3/2) + (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2) - (-self.magnet_radius + r)*(-(-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)) + (-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) + (-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)**2*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)*((-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 - (ep31*(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 - 2*ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3 + (-self.magnet_radius + r)**2*((-ep21*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2) + ep31)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)) - (self.magnet_radius + r)**2*(-(-2*self.magnet_radius + 2*r)/(self.magnet_radius + r)**2 + 2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**3)*(ep11*((-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) + ep21 + ep31*((-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)**2 + ((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) - 1)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/((-self.magnet_radius + r)**2*(2*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 - 2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))))/(self.magnet_radius + r)**2 - (-ep11*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + ep21)*(-(-2*self.magnet_radius - 2*r)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)**2 - (-2*self.magnet_radius + 2*r)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))*((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2)/((-2*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)/((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + 2)*((self.magnet_length/2 + Z)**2 + (-self.magnet_radius + r)**2)))/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1) - (-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)))/np.sqrt((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(np.pi*(self.magnet_radius + r)**2) + 2*self.magnet_radius*(-(-self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep12 + ep32)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep12 + ep32*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/np.sqrt((-self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2) + (self.magnet_length/2 + Z)*(-(-self.magnet_radius + r)*(-ep11 + ep31)/((self.magnet_radius + r)*(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1)) - (-ep11 + ep31*(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2)/(-(-self.magnet_radius + r)**2/(self.magnet_radius + r)**2 + 1))/np.sqrt((self.magnet_length/2 + Z)**2 + (self.magnet_radius + r)**2))/(np.pi*(self.magnet_radius + r)**3) diff --git a/tests/test_component/test_magnet_cylinder.py b/tests/test_component/test_magnet_cylinder.py deleted file mode 100644 index 1ec7b17..0000000 --- a/tests/test_component/test_magnet_cylinder.py +++ /dev/null @@ -1,129 +0,0 @@ -import pytest -import numpy as np -from mrfmsim.component import CylinderMagnet - - - -"""Test CylinderMagnet module in mrfmsim.component. - - -CylinderMagnet ------------- - -All sphere magnets are tested using the parameters: -radius = 0.5 nm -length = 10 nm -mu0_Ms = 1 mT -origin = [0, 0, 0] nm - -Bz_method -^^^^^^^^^^ - -1. Test Bz's output has the same shape as the input grid -2. Test Bz's output is symmetric along x-axis -3. Test Bz at poles (1.0, 2.0, 6.0) resulting in Bz value of 0.00391404 mT -4. Test Bz at poles (10.0, 0.0, 0.0) resulting in Bz value of -0.00044788490737216163 mT - -Bzx_method -^^^^^^^^^^ - -1. Test Bzx's output has the same shape as the input grid -2. Test Bzx's output is symmetric along x-axis -3. Test Bzx at poles (1.0, 2.0, 6.0) resulting in Bzx value of -0.00221805 mT -4. Test Bzx at poles (10.0, 0.0, 0.0) resulting in Bzx value of 0.00010754599 mT -5. Test Bzx at poles (0.0, 10.0, 0.0) resulting in Bzx value of 0.0 mT - - -Bzxx_method -^^^^^^^^^^ - -1. Test Bzxx's output has the same shape as the input grid -2. Test Bzxx's output is symmetric along x-axis -3. Test Bzxx at poles (1.0, 2.0, 6.0) resulting in Bzxx value of 0.0031995877 mT -4. Test Bzxx at poles (10.0, 0.0, 0.0) resulting in Bzxx value of -3.22679905171e-05 mT - - -""" - - - -class TestCylinderMagnet: - def setup_method(self): - self.magnet = CylinderMagnet( - magnet_radius=0.5, magnet_length=10, magnet_origin=[0, 0, 0], mu0_Ms=1 - ) - - # test the shape of the magnetic field to be the same as the input grid - def test_Bz_shape(self): - '''Test the shape of the magnetic field Bz to be the same as the input grid''' - grid = np.ogrid[-1:1:2j, -1:1:5j, -1:1:10j] - Bz = self.magnet.Bz_method(grid[0], grid[1], grid[2]) - assert Bz.shape == (2, 5, 10) - - def test_Bzx_shape(self): - '''Test the shape of the magnetic field Bzx to be the same as the input grid''' - grid = np.ogrid[-1:1:2j, -1:1:5j, -1:1:10j] - Bzx = self.magnet.Bzx_method(grid[0], grid[1], grid[2]) - assert Bzx.shape == (2, 5, 10) - - def test_Bzxx_shape(self): - '''Test the shape of the magnetic field Bzxx to be the same as the input grid''' - grid = np.ogrid[-1:1:2j, -1:1:5j, -1:1:10j] - Bzxx = self.magnet.Bzxx_method(grid[0], grid[1], grid[2]) - assert Bzxx.shape == (2, 5, 10) - - # test the symmetry of the magnetic field along x-axis - def test_Bz_symmetry(self): - '''Test the symmetry of the magnetic field Bz along x-axis''' - Bz1 = self.magnet.Bz_method(1, 2, 6) - Bz2 = self.magnet.Bz_method(-1, 2, 6) - assert np.allclose(Bz1, Bz2) - - def test_Bzx_symmetry(self): - '''Test the symmetry of the magnetic field Bzx along x-axis''' - Bzx1 = self.magnet.Bzx_method(1, 2, 6) - Bzx2 = self.magnet.Bzx_method(-1, 2, 6) - assert np.allclose(Bzx1, -Bzx2) # Bzx is antisymmetric - - def test_Bzxx_symmetry(self): - '''Test the symmetry of the magnetic field Bzxx along x-axis''' - Bzxx1 = self.magnet.Bzxx_method(1, 2, 6) - Bzxx2 = self.magnet.Bzxx_method(-1, 2, 6) - assert np.allclose(Bzxx1, Bzxx2) # Bzxx is symmetric - - # test the value of the magnetic field at poles(1.0, 2.0, 6.0) & (10.0, 0.0, 0.0) - def test_Bz_1(self): - '''Test the magnetic field Bz at near field''' - Bz = self.magnet.Bz_method(1, 2, 6) - assert np.allclose(Bz, 0.00391404, atol=1e-5) - - def test_Bzx_1(self): - '''Test the magnetic field Bzx at near field''' - Bzx = self.magnet.Bzx_method(1, 2, 6) - assert np.allclose(Bzx, -0.00221805, atol=1e-5) - - def test_Bzxx_1(self): - '''Test the magnetic field Bzxx at near field''' - Bzxx = self.magnet.Bzxx_method(1, 2, 6) - assert np.allclose(Bzxx, 0.0031995877, atol=1e-5) - - def test_Bz_2(self): - '''Test the magnetic field Bz at far field''' - Bz = self.magnet.Bz_method(10, 0, 0) - assert np.allclose(Bz, -0.00044788490737216163, atol=1e-5) - - def test_Bzx_2(self): - '''Test the magnetic field Bzx at far field''' - Bzx = self.magnet.Bzx_method(10, 0, 0) - assert np.allclose(Bzx, 0.00010754599, atol=1e-5) - - def test_Bzxx_2(self): - '''Test the magnetic field Bzxx at far field''' - Bzxx = self.magnet.Bzxx_method(10, 0, 0) - assert np.allclose(Bzxx, -3.22679905171e-05, atol=1e-5) - - # test the when x is 0, Bzx is 0 - def test_Bzx_when_x_is_0(self): - '''Test the magnetic field Bzx when x is 0''' - Bzx = self.magnet.Bzx_method(0, 10, 0) - assert np.allclose(Bzx, 0, atol=1e-10) From 9032701bf01077196a58943b7c64c2c850558e57 Mon Sep 17 00:00:00 2001 From: SKeeTElor Date: Thu, 23 Oct 2025 21:50:59 -0400 Subject: [PATCH 23/45] Modulate the test of CylinderMagnetApproxByRect The old test rely on CylinderMagnet, which is deleted now --- .../test_magnet_cylinder_approx.py | 114 ++++++++---------- 1 file changed, 50 insertions(+), 64 deletions(-) diff --git a/tests/test_component/test_magnet_cylinder_approx.py b/tests/test_component/test_magnet_cylinder_approx.py index 76b2844..e33e52f 100644 --- a/tests/test_component/test_magnet_cylinder_approx.py +++ b/tests/test_component/test_magnet_cylinder_approx.py @@ -6,7 +6,7 @@ """Test CylinderMagnetApproxByRect module in mrfmsim.component. -CylinderMagnet & CylinderMagnetApproxByRect +CylinderMagnetApproxByRect ------------ All sphere magnets are tested using the parameters: @@ -44,99 +44,85 @@ """ + + class TestCylinderMagnet: def setup_method(self): - self.magnet = CylinderMagnet( - magnet_radius=0.5, magnet_length=10, magnet_origin=[0, 0, 0], mu0_Ms=1 - ) - self.magnet_approx = CylinderMagnetApproxByRect( + self.magnet = CylinderMagnetApproxByRect( magnet_radius=0.5, magnet_length=10, magnet_origin=[0, 0, 0], mu0_Ms=1 ) - # test the shape of the magnetic field + # test the shape of the magnetic field to be the same as the input grid def test_Bz_shape(self): '''Test the shape of the magnetic field Bz to be the same as the input grid''' grid = np.ogrid[-1:1:2j, -1:1:5j, -1:1:10j] - Bz = self.magnet_approx.Bz_method(grid[0], grid[1], grid[2]) + Bz = self.magnet.Bz_method(grid[0], grid[1], grid[2]) assert Bz.shape == (2, 5, 10) def test_Bzx_shape(self): '''Test the shape of the magnetic field Bzx to be the same as the input grid''' grid = np.ogrid[-1:1:2j, -1:1:5j, -1:1:10j] - Bzx = self.magnet_approx.Bzx_method(grid[0], grid[1], grid[2]) + Bzx = self.magnet.Bzx_method(grid[0], grid[1], grid[2]) assert Bzx.shape == (2, 5, 10) def test_Bzxx_shape(self): '''Test the shape of the magnetic field Bzxx to be the same as the input grid''' grid = np.ogrid[-1:1:2j, -1:1:5j, -1:1:10j] - Bzxx = self.magnet_approx.Bzxx_method(grid[0], grid[1], grid[2]) + Bzxx = self.magnet.Bzxx_method(grid[0], grid[1], grid[2]) assert Bzxx.shape == (2, 5, 10) - # test the symmetry of the magnetic field + # test the symmetry of the magnetic field along x-axis def test_Bz_symmetry(self): - '''Test the x-axis symmetry of the magnetic field Bz''' - Bz1 = self.magnet_approx.Bz_method(1, 2, 6) - Bz2 = self.magnet_approx.Bz_method(-1, 2, 6) + '''Test the symmetry of the magnetic field Bz along x-axis''' + Bz1 = self.magnet.Bz_method(1, 2, 6) + Bz2 = self.magnet.Bz_method(-1, 2, 6) assert np.allclose(Bz1, Bz2) def test_Bzx_symmetry(self): - '''Test the x-axis antisymmetry of the magnetic field Bzx''' - Bzx1 = self.magnet_approx.Bzx_method(1, 2, 6) - Bzx2 = self.magnet_approx.Bzx_method(-1, 2, 6) + '''Test the symmetry of the magnetic field Bzx along x-axis''' + Bzx1 = self.magnet.Bzx_method(1, 2, 6) + Bzx2 = self.magnet.Bzx_method(-1, 2, 6) assert np.allclose(Bzx1, -Bzx2) # Bzx is antisymmetric def test_Bzxx_symmetry(self): - '''Test the x-axis symmetry of the magnetic field Bzxx''' - Bzxx1 = self.magnet_approx.Bzxx_method(1, 2, 6) - Bzxx2 = self.magnet_approx.Bzxx_method(-1, 2, 6) + '''Test the symmetry of the magnetic field Bzxx along x-axis''' + Bzxx1 = self.magnet.Bzxx_method(1, 2, 6) + Bzxx2 = self.magnet.Bzxx_method(-1, 2, 6) assert np.allclose(Bzxx1, Bzxx2) # Bzxx is symmetric - # test the value of the magnetic field - def test_Bz_NearField(self): - '''Test the near field of the magnetic field Bz to be close to the exact value''' - grid = np.ogrid[-3:3:10j, -3:3:10j, 6:7:2j] - Bz_approx = self.magnet_approx.Bz_method(grid[0], grid[1], grid[2]) - Bz_exact = self.magnet.Bz_method(grid[0], grid[1], grid[2]) - assert np.allclose(Bz_approx, Bz_exact, rtol=1e-3) - - def test_Bzx_NearField(self): - '''Test the near field of the magnetic field Bzx to be close to the exact value''' - grid = np.ogrid[-3:3:10j, -3:3:10j, 6:7:2j] - Bzx_approx = self.magnet_approx.Bzx_method(grid[0], grid[1], grid[2]) - Bzx_exact = self.magnet.Bzx_method(grid[0], grid[1], grid[2]) - assert np.allclose(Bzx_approx, Bzx_exact, rtol=1e-3) - - def test_Bzxx_NearField(self): - '''Test the near field of the magnetic field Bzxx to be close to the exact value''' - grid = np.ogrid[-3:3:10j, -3:3:10j, 6:7:2j] - Bzxx_approx = self.magnet_approx.Bzxx_method(grid[0], grid[1], grid[2]) - Bzxx_exact = self.magnet.Bzxx_method(grid[0], grid[1], grid[2]) - assert np.allclose(Bzxx_approx, Bzxx_exact, rtol=1e-3) - - def test_Bz_FarField(self): - '''Test the far field of the magnetic field Bz to be close to the exact value''' - grid = np.ogrid[-13:-10:10j, -1:2:10j, 6:7:2j] - Bz_approx = self.magnet_approx.Bz_method(grid[0], grid[1], grid[2]) - Bz_exact = self.magnet.Bz_method(grid[0], grid[1], grid[2]) - assert np.allclose(Bz_approx, Bz_exact, atol=1e-4) - - def test_Bzx_FarField(self): - '''Test the far field of the magnetic field Bzx to be close to the exact value''' - grid = np.ogrid[-13:-10:10j, -1:2:10j, 6:7:2j] - Bzx_approx = self.magnet_approx.Bzx_method(grid[0], grid[1], grid[2]) - Bzx_exact = self.magnet.Bzx_method(grid[0], grid[1], grid[2]) - assert np.allclose(Bzx_approx, Bzx_exact, atol=1e-6) - - def test_Bzxx_FarField(self): - '''Test the far field of the magnetic field Bzxx to be close to the exact value''' - grid = np.ogrid[-13:-10:10j, -1:2:10j, 6:7:2j] - Bzxx_approx = self.magnet_approx.Bzxx_method(grid[0], grid[1], grid[2]) - Bzxx_exact = self.magnet.Bzxx_method(grid[0], grid[1], grid[2]) - assert np.allclose(Bzxx_approx, Bzxx_exact, atol=1e-6) - + # test the value of the magnetic field at poles(1.0, 2.0, 6.0) & (10.0, 0.0, 0.0) + def test_Bz_1(self): + '''Test the magnetic field Bz at near field''' + Bz = self.magnet.Bz_method(1, 2, 6) + assert np.allclose(Bz, 0.00391404, atol=1e-5) + + def test_Bzx_1(self): + '''Test the magnetic field Bzx at near field''' + Bzx = self.magnet.Bzx_method(1, 2, 6) + assert np.allclose(Bzx, -0.00221805, atol=1e-5) + + def test_Bzxx_1(self): + '''Test the magnetic field Bzxx at near field''' + Bzxx = self.magnet.Bzxx_method(1, 2, 6) + assert np.allclose(Bzxx, 0.0031995877, atol=1e-5) + + def test_Bz_2(self): + '''Test the magnetic field Bz at far field''' + Bz = self.magnet.Bz_method(10, 0, 0) + assert np.allclose(Bz, -0.00044788490737216163, atol=1e-5) + + def test_Bzx_2(self): + '''Test the magnetic field Bzx at far field''' + Bzx = self.magnet.Bzx_method(10, 0, 0) + assert np.allclose(Bzx, 0.00010754599, atol=1e-5) + + def test_Bzxx_2(self): + '''Test the magnetic field Bzxx at far field''' + Bzxx = self.magnet.Bzxx_method(10, 0, 0) + assert np.allclose(Bzxx, -3.22679905171e-05, atol=1e-5) # test the when x is 0, Bzx is 0 def test_Bzx_when_x_is_0(self): - '''Test the magnetic field Bzx when x is 0 to be 0''' - Bzx = self.magnet_approx.Bzx_method(0, 10, 0) + '''Test the magnetic field Bzx when x is 0''' + Bzx = self.magnet.Bzx_method(0, 10, 0) assert np.allclose(Bzx, 0, atol=1e-10) From bde2e03db589c9a788e9b126bce0459a6c3b700d Mon Sep 17 00:00:00 2001 From: Peter Sun Date: Fri, 24 Oct 2025 00:26:41 -0400 Subject: [PATCH 24/45] Refactor cylinder magnet class --- mrfmsim/component/__init__.py | 3 +- ...t_cylinder_approx.py => cylindermagnet.py} | 4 +- ...inder_approx.py => test_cylindermagnet.py} | 82 +++++++++++-------- 3 files changed, 51 insertions(+), 38 deletions(-) rename mrfmsim/component/{magnet_cylinder_approx.py => cylindermagnet.py} (99%) rename tests/test_component/{test_magnet_cylinder_approx.py => test_cylindermagnet.py} (64%) diff --git a/mrfmsim/component/__init__.py b/mrfmsim/component/__init__.py index a4e8f8e..defd808 100644 --- a/mrfmsim/component/__init__.py +++ b/mrfmsim/component/__init__.py @@ -1,6 +1,7 @@ from .base import ComponentBase from .magnet import SphereMagnet, RectangularMagnet +from .cylindermagnet import CylinderMagnetApprox from .cantilever import Cantilever from .grid import Grid from .sample import Sample -from .magnet_cylinder_approx import CylinderMagnetApproxByRect + diff --git a/mrfmsim/component/magnet_cylinder_approx.py b/mrfmsim/component/cylindermagnet.py similarity index 99% rename from mrfmsim/component/magnet_cylinder_approx.py rename to mrfmsim/component/cylindermagnet.py index cad17b1..b8667ec 100644 --- a/mrfmsim/component/magnet_cylinder_approx.py +++ b/mrfmsim/component/cylindermagnet.py @@ -5,8 +5,8 @@ @dataclass -class CylinderMagnetApproxByRect(ComponentBase): - """Cylinder magnet object with its Bz, Bzx, Bzxx calculations. +class CylinderMagnetApprox(ComponentBase): + """Cylinder magnet object approximated by Rectangular Magnets. :param float radius: cylinder magnet radius [nm] :param float length: cylinder magnet length [nm] diff --git a/tests/test_component/test_magnet_cylinder_approx.py b/tests/test_component/test_cylindermagnet.py similarity index 64% rename from tests/test_component/test_magnet_cylinder_approx.py rename to tests/test_component/test_cylindermagnet.py index e33e52f..637f2c1 100644 --- a/tests/test_component/test_magnet_cylinder_approx.py +++ b/tests/test_component/test_cylindermagnet.py @@ -1,13 +1,12 @@ -import pytest import numpy as np -from mrfmsim.component import CylinderMagnet, CylinderMagnetApproxByRect +from mrfmsim.component import CylinderMagnetApprox -"""Test CylinderMagnetApproxByRect module in mrfmsim.component. +"""Test CylinderMagnet module in mrfmsim.component. -CylinderMagnetApproxByRect ------------- +CylinderMagnetApprox +-------------------- All sphere magnets are tested using the parameters: radius = 0.5 nm @@ -32,97 +31,110 @@ 4. Test Bzx in the far field is close to the exact value 5. Test Bzx when x is 0, Bzx is 0 - Bzxx_method -^^^^^^^^^^ +^^^^^^^^^^^ 1. Test Bzxx's output has the same shape as the input grid 2. Test Bzxx's output is symmetric along x-axis 3. Test Bzxx in the near field is close to the exact value 4. Test Bzxx in the far field is close to the exact value - - """ - class TestCylinderMagnet: def setup_method(self): - self.magnet = CylinderMagnetApproxByRect( + self.magnet = CylinderMagnetApprox( magnet_radius=0.5, magnet_length=10, magnet_origin=[0, 0, 0], mu0_Ms=1 ) - # test the shape of the magnetic field to be the same as the input grid def test_Bz_shape(self): - '''Test the shape of the magnetic field Bz to be the same as the input grid''' + """Test the shape of the magnetic field Bz to be the same as the input grid.""" grid = np.ogrid[-1:1:2j, -1:1:5j, -1:1:10j] Bz = self.magnet.Bz_method(grid[0], grid[1], grid[2]) assert Bz.shape == (2, 5, 10) def test_Bzx_shape(self): - '''Test the shape of the magnetic field Bzx to be the same as the input grid''' + """Test the shape of the magnetic field Bzx to be the same as the input grid.""" grid = np.ogrid[-1:1:2j, -1:1:5j, -1:1:10j] Bzx = self.magnet.Bzx_method(grid[0], grid[1], grid[2]) assert Bzx.shape == (2, 5, 10) def test_Bzxx_shape(self): - '''Test the shape of the magnetic field Bzxx to be the same as the input grid''' + '''Test the shape of the magnetic field Bzxx to be the same as the input grid.''' grid = np.ogrid[-1:1:2j, -1:1:5j, -1:1:10j] Bzxx = self.magnet.Bzxx_method(grid[0], grid[1], grid[2]) assert Bzxx.shape == (2, 5, 10) - # test the symmetry of the magnetic field along x-axis def test_Bz_symmetry(self): - '''Test the symmetry of the magnetic field Bz along x-axis''' + """Test the symmetry of the magnetic field Bz along x-axis.""" Bz1 = self.magnet.Bz_method(1, 2, 6) Bz2 = self.magnet.Bz_method(-1, 2, 6) assert np.allclose(Bz1, Bz2) def test_Bzx_symmetry(self): - '''Test the symmetry of the magnetic field Bzx along x-axis''' + """Test the symmetry of the magnetic field Bzx along x-axis.""" Bzx1 = self.magnet.Bzx_method(1, 2, 6) Bzx2 = self.magnet.Bzx_method(-1, 2, 6) assert np.allclose(Bzx1, -Bzx2) # Bzx is antisymmetric def test_Bzxx_symmetry(self): - '''Test the symmetry of the magnetic field Bzxx along x-axis''' + """Test the symmetry of the magnetic field Bzxx along x-axis.""" Bzxx1 = self.magnet.Bzxx_method(1, 2, 6) Bzxx2 = self.magnet.Bzxx_method(-1, 2, 6) assert np.allclose(Bzxx1, Bzxx2) # Bzxx is symmetric - # test the value of the magnetic field at poles(1.0, 2.0, 6.0) & (10.0, 0.0, 0.0) - def test_Bz_1(self): - '''Test the magnetic field Bz at near field''' + def test_Bz_near_field(self): + """Test the magnetic field Bz at near field. + + Test at poles (1.0, 2.0, 6.0). + """ Bz = self.magnet.Bz_method(1, 2, 6) assert np.allclose(Bz, 0.00391404, atol=1e-5) - def test_Bzx_1(self): - '''Test the magnetic field Bzx at near field''' + def test_Bzx_near_field(self): + """Test the magnetic field Bzx at near field. + + Test at poles (1.0, 2.0, 6.0). + """ Bzx = self.magnet.Bzx_method(1, 2, 6) assert np.allclose(Bzx, -0.00221805, atol=1e-5) - def test_Bzxx_1(self): - '''Test the magnetic field Bzxx at near field''' + def test_Bzxx_near_field(self): + """Test the magnetic field Bzxx at near field. + + Test at poles (1.0, 2.0, 6.0). + """ Bzxx = self.magnet.Bzxx_method(1, 2, 6) assert np.allclose(Bzxx, 0.0031995877, atol=1e-5) - def test_Bz_2(self): - '''Test the magnetic field Bz at far field''' + def test_Bz_far_field(self): + """Test the magnetic field Bz at far field. + + Test at (10.0, 0.0, 0.0). + """ Bz = self.magnet.Bz_method(10, 0, 0) assert np.allclose(Bz, -0.00044788490737216163, atol=1e-5) - def test_Bzx_2(self): - '''Test the magnetic field Bzx at far field''' + def test_Bzx_far_field(self): + """Test the magnetic field Bzx at far field. + + Test at (10.0, 0.0, 0.0). + """ Bzx = self.magnet.Bzx_method(10, 0, 0) assert np.allclose(Bzx, 0.00010754599, atol=1e-5) - def test_Bzxx_2(self): - '''Test the magnetic field Bzxx at far field''' + def test_Bzxx_far_field(self): + """Test the magnetic field Bzxx at far field. + + Test at (10.0, 0.0, 0.0). + """ Bzxx = self.magnet.Bzxx_method(10, 0, 0) assert np.allclose(Bzxx, -3.22679905171e-05, atol=1e-5) - # test the when x is 0, Bzx is 0 - def test_Bzx_when_x_is_0(self): - '''Test the magnetic field Bzx when x is 0''' + def test_Bzx_x_is_0(self): + """Test the magnetic field Bzx when x is 0. + + Test at (0.0, 10.0, 0.0). + """ Bzx = self.magnet.Bzx_method(0, 10, 0) assert np.allclose(Bzx, 0, atol=1e-10) From f068021684cd8e634ddb2020ed047305d3f4b195 Mon Sep 17 00:00:00 2001 From: Peter Sun Date: Fri, 24 Oct 2025 00:29:13 -0400 Subject: [PATCH 25/45] Refactor time dependent polarization test --- tests/test_formula/test_polarization.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_formula/test_polarization.py b/tests/test_formula/test_polarization.py index aadb779..5c348c6 100644 --- a/tests/test_formula/test_polarization.py +++ b/tests/test_formula/test_polarization.py @@ -190,7 +190,8 @@ def test_rel_dpol_sat_td_NaN(sample_e): rpol_b = pol.rel_dpol_sat_td( Bzx, 1.0, ext_B_offset_b, 1, sample_e.Gamma, sample_e.T2, 2000 ) - assert (not np.isnan(rpol_a)) and (not np.isnan(rpol_b)) + assert not np.any(np.isnan(rpol_a)) + assert not np.any(np.isnan(rpol_b)) def test_rel_dpol_sat_td_without_td(sample_e): From 88281577de65fcb16221d011f67c9a495dfb9e8f Mon Sep 17 00:00:00 2001 From: Peter Sun Date: Fri, 24 Oct 2025 00:53:45 -0400 Subject: [PATCH 26/45] Add cylindermagnet module in magnet documentation --- docs/setup/magnet.rst | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/setup/magnet.rst b/docs/setup/magnet.rst index 1a0f769..1cd5b0d 100644 --- a/docs/setup/magnet.rst +++ b/docs/setup/magnet.rst @@ -12,7 +12,7 @@ Currently, the two types of magnets supported are mrfmsim.component.magnet.SphereMagnet mrfmsim.component.magnet.RectangularMagnet - mrfmsim.component.magnet_cylinder_approx.CylinderMagnetApproxByRect + mrfmsim.component.cylindermagnet.CylinderMagnetApprox Example Usage ------------- @@ -42,3 +42,12 @@ To display the magnet information: :members: :undoc-members: :show-inheritance: + + +:mod:`cylindermagnet` module +---------------------------- + +.. automodule:: mrfmsim.component.cylindermagnet + :members: + :undoc-members: + :show-inheritance: From 47bf20adc322a9e0fa0c5dff0675cfd3a8f97227 Mon Sep 17 00:00:00 2001 From: SKeeTElor Date: Fri, 24 Oct 2025 11:22:14 -0400 Subject: [PATCH 27/45] Delete cermittd_fast.py and add polarization.py These 2 files are no longger useful --- mrfmsim/experiment/cermittd_fast.py | 69 ----------------------------- mrfmsim/formula/polarization.py | 39 +--------------- 2 files changed, 1 insertion(+), 107 deletions(-) delete mode 100644 mrfmsim/experiment/cermittd_fast.py diff --git a/mrfmsim/experiment/cermittd_fast.py b/mrfmsim/experiment/cermittd_fast.py deleted file mode 100644 index f4f4833..0000000 --- a/mrfmsim/experiment/cermittd_fast.py +++ /dev/null @@ -1,69 +0,0 @@ -from mrfmsim import formula -from mrfmsim import Node, ExperimentGroup -from .stdelements import STANDARD_NODES, STANDARD_COMPONENTS - -node_objects = [ - Node("rel_dpol td_sat", formula.masked_rel_dpol_sat_td_gridwithpol, output="grid_pol"), - Node("rel_dpol averaged", formula.rel_dpol_multipulse, output="rel_dpol_avg"), - Node( - "spring constant shift td", - formula.neg_sum_of_product, - inputs=["Bzxx_pol", "rel_dpol_avg", "mz_eq", "spin_density", "grid_voxel"], - output="dk_spin", - doc="Calculate dk_spin account for the negative sign in the approximation.", - ), - Node( - "Bzxx_pol", - formula.field_func, - inputs=["Bzxx_method", "grid_pol", "h"], - output="Bzxx_pol", - ), -] - -CermitTD_edges = [ - ["grid extended", "Bz extended"], - ["Bz extended", "B_tot extended"], - ["B_tot extended", ["B_tot sliced", "B_offset extended"]], - ["B_tot sliced", "mz_eq"], - [["B_offset extended", "Bzx", "x_0p window pts"], "rel_dpol td_sat"], - ["rel_dpol td_sat", "rel_dpol averaged"], - [["mz_eq", "Bzxx", "rel_dpol averaged"], "spring constant shift td"], - ["spring constant shift td", "frequency shift"], -] - -CermitTDSmallTip_edges = [ - ["grid extended", ["Bz extended", "Bzx extended"]], - ["Bz extended", "B_tot extended"], - ["B_tot extended", ["B_tot sliced", "B_offset extended"]], - ["B_tot sliced", "mz_eq"], - [["B_offset extended", "Bzx extended", "x_0p window pts"], "rel_dpol small_steps"], - ["rel_dpol small_steps", "rel_dpol averaged"], - [["mz_eq", "Bzxx trapz", "rel_dpol averaged"], "spring constant shift trapz td"], - ["spring constant shift trapz td", "frequency shift"], -] - -experiment_recipes = { - "CermitTD": { - "grouped_edges": CermitTD_edges, - "doc": "Time-dependent CERMIT experiment for a large tip.", - }, - "CermitTDSmallTip": { - "grouped_edges": CermitTDSmallTip_edges, - "doc": "Time-dependent CERMIT experiment for a small tip.", - }, -} - -docstring = """\ -Simulates a Cornell-style frequency shift magnetic -resonance force microscope experiment considering the time-dependent -nature of the saturation, averaged over multiple pulses and with -small-step approximation. -""" - -CermitTDGroup = ExperimentGroup( - name="CermitTDGroup", - node_objects=list(STANDARD_NODES) + node_objects, - experiment_recipes=experiment_recipes, - experiment_defaults={"components": STANDARD_COMPONENTS}, - doc=docstring, -) diff --git a/mrfmsim/formula/polarization.py b/mrfmsim/formula/polarization.py index b36eef8..900a63a 100644 --- a/mrfmsim/formula/polarization.py +++ b/mrfmsim/formula/polarization.py @@ -288,41 +288,4 @@ def rel_dpol_multipulse(rel_dpol, T1, dt_pulse): t_r = dt_pulse / T1 rel_dpol_avg = (np.exp(t_r) - 1) * rel_dpol / t_r / (np.exp(t_r) - pol) - return rel_dpol_avg - - -def masked_rel_dpol_sat_td_gridwithpol(Bzx, B1, ext_B_offset, ext_pts, Gamma, T2, grid_array,tip_v,void_mask): - """Relative change in polarization for time-dependent saturation. - - The result is not a steady-state solution because it ignores T1 relaxation. - - Binarizing the polarization with 0 and 1, then retrun the girds that has pol with 1 (pol>0.5). - """ - # ignore division error the Exp takes care of the inf, and nan - np.seterr(divide="ignore", invalid="ignore") - - omega_offset_atan = np.arctan(ext_B_offset * Gamma * T2) - - atan_omega_i = omega_offset_atan[: -ext_pts * 2] - atan_omega_f = omega_offset_atan[ext_pts * 2 :] - - div = np.divide(atan_omega_f - atan_omega_i, Bzx) - - # adjust for the center slice of the discontinuous issue - nan_indices = np.where(np.isnan(div))[0] - if len(nan_indices) > 0: # get the first nan element x index - div[nan_indices[0]] = (div[nan_indices[0] + 1]) - - - rt = Gamma * B1**2 * np.abs(div) / tip_v*void_mask - dpol = np.exp(-rt) - - indices = np.where(dpol < 0.5) - - x = grid_array[0].flatten() - y = grid_array[1].flatten() - z = grid_array[2].flatten() - - grid_pol = np.array([x[indices[0][:]],y[indices[1][:]],z[indices[2][:]]]) - - return grid_pol.T \ No newline at end of file + return rel_dpol_avg \ No newline at end of file From 12914e9f73b922add348e1a28460fde773454fc0 Mon Sep 17 00:00:00 2001 From: SKeeTElor Date: Fri, 24 Oct 2025 20:10:06 -0400 Subject: [PATCH 28/45] Fix the bug in the test --- tests/test_component/test_cylindermagnet.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_component/test_cylindermagnet.py b/tests/test_component/test_cylindermagnet.py index 637f2c1..edff1cb 100644 --- a/tests/test_component/test_cylindermagnet.py +++ b/tests/test_component/test_cylindermagnet.py @@ -113,7 +113,7 @@ def test_Bz_far_field(self): Test at (10.0, 0.0, 0.0). """ Bz = self.magnet.Bz_method(10, 0, 0) - assert np.allclose(Bz, -0.00044788490737216163, atol=1e-5) + assert np.allclose(Bz, (-0.00045051510382442363), atol=1e-4) def test_Bzx_far_field(self): """Test the magnetic field Bzx at far field. @@ -121,7 +121,7 @@ def test_Bzx_far_field(self): Test at (10.0, 0.0, 0.0). """ Bzx = self.magnet.Bzx_method(10, 0, 0) - assert np.allclose(Bzx, 0.00010754599, atol=1e-5) + assert np.allclose(Bzx, 0.00010817803386829378, atol=1e-4) def test_Bzxx_far_field(self): """Test the magnetic field Bzxx at far field. @@ -129,7 +129,7 @@ def test_Bzxx_far_field(self): Test at (10.0, 0.0, 0.0). """ Bzxx = self.magnet.Bzxx_method(10, 0, 0) - assert np.allclose(Bzxx, -3.22679905171e-05, atol=1e-5) + assert np.allclose(Bzxx, -3.245766094831442e-05, atol=1e-4) def test_Bzx_x_is_0(self): """Test the magnetic field Bzx when x is 0. From 7d545460dbb54c5a75c151a9c81e19b2951c5b19 Mon Sep 17 00:00:00 2001 From: SKeeTElor Date: Fri, 24 Oct 2025 20:37:27 -0400 Subject: [PATCH 29/45] Fix 3 new bugs in test --- tests/test_component/test_cylindermagnet.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_component/test_cylindermagnet.py b/tests/test_component/test_cylindermagnet.py index edff1cb..bc9506a 100644 --- a/tests/test_component/test_cylindermagnet.py +++ b/tests/test_component/test_cylindermagnet.py @@ -89,7 +89,7 @@ def test_Bz_near_field(self): Test at poles (1.0, 2.0, 6.0). """ Bz = self.magnet.Bz_method(1, 2, 6) - assert np.allclose(Bz, 0.00391404, atol=1e-5) + assert np.allclose(Bz, 0.003938311762612047, atol=1e-5) def test_Bzx_near_field(self): """Test the magnetic field Bzx at near field. @@ -97,7 +97,7 @@ def test_Bzx_near_field(self): Test at poles (1.0, 2.0, 6.0). """ Bzx = self.magnet.Bzx_method(1, 2, 6) - assert np.allclose(Bzx, -0.00221805, atol=1e-5) + assert np.allclose(Bzx, -0.0022319789019074046, atol=1e-5) def test_Bzxx_near_field(self): """Test the magnetic field Bzxx at near field. @@ -105,7 +105,7 @@ def test_Bzxx_near_field(self): Test at poles (1.0, 2.0, 6.0). """ Bzxx = self.magnet.Bzxx_method(1, 2, 6) - assert np.allclose(Bzxx, 0.0031995877, atol=1e-5) + assert np.allclose(Bzxx, -0.00035144076191428254, atol=1e-5) def test_Bz_far_field(self): """Test the magnetic field Bz at far field. From f8142a52b3d65d3c3c557f03aac416b5ba576862 Mon Sep 17 00:00:00 2001 From: SKeeTElor Date: Fri, 24 Oct 2025 21:00:33 -0400 Subject: [PATCH 30/45] fix docstring format --- tests/test_component/test_cylindermagnet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_component/test_cylindermagnet.py b/tests/test_component/test_cylindermagnet.py index bc9506a..addbcbf 100644 --- a/tests/test_component/test_cylindermagnet.py +++ b/tests/test_component/test_cylindermagnet.py @@ -60,7 +60,7 @@ def test_Bzx_shape(self): assert Bzx.shape == (2, 5, 10) def test_Bzxx_shape(self): - '''Test the shape of the magnetic field Bzxx to be the same as the input grid.''' + """Test the shape of the magnetic field Bzxx to be the same as the input grid.""" grid = np.ogrid[-1:1:2j, -1:1:5j, -1:1:10j] Bzxx = self.magnet.Bzxx_method(grid[0], grid[1], grid[2]) assert Bzxx.shape == (2, 5, 10) From 833ce294d89c7b7e1db62b7f155d33b41f335137 Mon Sep 17 00:00:00 2001 From: Peter Sun Date: Wed, 29 Oct 2025 16:07:53 -0400 Subject: [PATCH 31/45] Fix cylinder magnet and tests docstring --- mrfmsim/component/cylindermagnet.py | 170 ++++++++++---------- tests/test_component/test_cylindermagnet.py | 26 +-- tests/test_formula/test_polarization.py | 7 +- 3 files changed, 101 insertions(+), 102 deletions(-) diff --git a/mrfmsim/component/cylindermagnet.py b/mrfmsim/component/cylindermagnet.py index b8667ec..c3076b6 100644 --- a/mrfmsim/component/cylindermagnet.py +++ b/mrfmsim/component/cylindermagnet.py @@ -8,9 +8,9 @@ class CylinderMagnetApprox(ComponentBase): """Cylinder magnet object approximated by Rectangular Magnets. - :param float radius: cylinder magnet radius [nm] - :param float length: cylinder magnet length [nm] - :param tuple origin: the position of the magnet origin (x, y, z) + :param float magnet_radius: cylinder magnet radius [nm] + :param float magnet_length: cylinder magnet length [nm] + :param tuple magnet_origin: the position of the magnet origin (x, y, z) :param float mu0_Ms: saturation magnetization [mT] """ @@ -121,19 +121,15 @@ def __post_init__(self): def Bz_method(self, x, y, z): r"""Calculate magnetic field :math:`B_z` [mT]. - Approxing Cylinder Magnet by 11 Rectangular Magnet. When viewed from the - vertical direction, we are using a row of rectangles to approximate a circle, - these rectangular blocks are arranged side by side, with the following lengths - and widths: + Approximating Cylinder Magnet by 11 Rectangular Magnets. When viewed from the + vertical direction, we are using a row of rectangles to approximate a circle, + these rectangular blocks are arranged side by side. - (6,1)(10,1)(14,1)(16,2)(18,2)(20,6)(18,2)(16,2)(14,1)(10,1)(6,1) - - This is arroximation for a circle with a diameter of 20, these shapes if found by - Minecraft community.The magnetic field is given by the sum of the magnetic fields - of these 11 rectangles. - - - The magnetic field of RectangularMagnet is calculated following Ravaud2009. + The magnetic field of each rectangular magnet is calculated following the + method described in Ravaud2009 [1]_. The magnet is set up so that the + :math:`x` and :math:`y` dimensions are centered about the zero point. + The translation in :math:`z` shifts the tip of the magnet in the + :math:`z`-direction to be the given distance from the surface. Using the Coulombian model, assuming a uniform magnetization throughout the volume of the magnet and modeling each face of the magnet as a layer of continuous current density. The total field is found by @@ -143,33 +139,28 @@ def Bz_method(self, x, y, z): .. math:: B_z = \dfrac{\mu_0 M_s}{4\pi} \sum_{i=1}^{2} \sum_{j=1}^2 \sum_{k=1}^2(-1)^{i+j+k} - arctan \left( \dfrac{(x - x_i)(y - y_i))}{(z - z_k)R} \right) + \arctan \left( \dfrac{(x - x_i)(y - y_i))}{(z - z_k)R} \right) Here :math:`(x,y,z)` are the coordinates for the location at which we want to know the field; - The magnet spans from x1 to x2 in the ``x``-direction, - y1 to y2 in the ``y``-direction, and z1 to z2 in - the ``z``-direction; + The magnet spans from :math:`x_1` to :math:`x_2` in the :math:`x`-direction, + :math:`y_1` to :math:`y_2` in the :math:`y`-direction, and :math:`z_1` to + :math:`z_2` in the :math:`z`-direction; .. math:: R = \sqrt{(x - x_i)^2 + (y - y_j)^2 + (z - z_k)^2} where :math:`\mu_0 M_s` is the magnet's saturation magnetization in mT. - **Reference**: - Ravaud, R. and Lemarquand, G. "Magnetic field produced by a - parallelepipedic magnet of various and uniform polarization" , - *PIER*, **2009**, *98*, 207-219 - [`10.2528/PIER09091704 `__]. + .. [1] Ravaud, R. and Lemarquand, G. "Magnetic field produced by a + parallelepipedic magnet of various and uniform polarization" , + *PIER*, **2009**, *98*, 207-219 + [`10.2528/PIER09091704 `__]. - - set the magnet up so that the x and y dimensions are centered about - the zero point. - - The translation in z should shift the tip of the magnet in the - z-direction to be the given distance from the surface. - :param float x: x coordinate of sample grid [nm] - :param float y: y coordinate of sample grid [nm] - :param float z: z coordinate of sample grid [nm] + :param float x: :math:`x` coordinate of sample grid [nm] + :param float y: :math:`y` coordinate of sample grid [nm] + :param float z: :math:`z` coordinate of sample grid [nm] """ dx11, dx12 = x - self._range[0][0], x - self._range[0][1] dy11, dy12 = y - self._range[0][2], y - self._range[0][3] @@ -247,13 +238,20 @@ def Bz_method(self, x, y, z): def _bz(dx1, dx2, dy1, dy2, dz1, dz2): """Calculate the summation term for magnetic field optimized by numba. - See method bz for the explanation. - :param float dx1, dx2: distance between grid and the one end of magnet - in x direction [nm] - :param float dy1, dy2: distance between grid and the one end of magnet - in y direction [nm] - :param float dz1, dz2: distance between grid and the one end of magnet - in z direction [nm] + See method Bz_method for the explanation. + + :param float dx1: distance between grid and one end of magnet + in :math:`x` direction [nm] + :param float dx2: distance between grid and other end of magnet + in :math:`x` direction [nm] + :param float dy1: distance between grid and one end of magnet + in :math:`y` direction [nm] + :param float dy2: distance between grid and other end of magnet + in :math:`y` direction [nm] + :param float dz1: distance between grid and one end of magnet + in :math:`z` direction [nm] + :param float dz2: distance between grid and other end of magnet + in :math:`z` direction [nm] """ return ( @@ -270,19 +268,12 @@ def _bz(dx1, dx2, dy1, dy2, dz1, dz2): def Bzx_method(self, x, y, z): r"""Calculate magnetic field gradient :math:`B_{zx}`. - Approxing Cylinder Magnet by 11 Rectangular Magnet. When viewed from the - vertical direction, we are using a row of rectangles to approximate a circle, - these rectangular blocks are arranged side by side, with the following lengths - and widths: - - (6,1)(10,1)(14,1)(16,2)(18,2)(20,6)(18,2)(16,2)(14,1)(10,1)(6,1) - - This is arroximation for a circle with a diameter of 20, these shapes if found by - Minecraft community.The magnetic field is given by the sum of the magnetic fields - of these 11 rectangles. + Approximating Cylinder Magnet by 11 Rectangular Magnets. When viewed from the + vertical direction, we are using a row of rectangles to approximate a circle, + these rectangular blocks are arranged side by side. The magnetic field gradient for RectangularMagnet is: - math:`B_{zx} = \dfrac{\partial{B_z}}{\partial x}` is + :math:`B_{zx} = \dfrac{\partial{B_z}}{\partial x}` is given by the following: .. math:: @@ -293,17 +284,17 @@ def Bzx_method(self, x, y, z): As described above, :math:`(x,y,z)` are coordinates for the location at which we want to know the field gradient; the magnet spans from - x1 to x2 in the ``x``-direction, y1 to y2 in the ``y``-direction, and - from z1 to z2 in the ``z``-direction; + x1 to x2 in the :math:`x`-direction, y1 to y2 in the :math:`y`-direction, and + from z1 to z2 in the :math:`z`-direction; .. math:: - R = \sqrt{(x - x_i) + (y - y_j) + (z - z_k)} + R = \sqrt{(x - x_i)^2 + (y - y_j)^2 + (z - z_k)^2} :math:`\mu_0 M_s` is the magnet's saturation magnetization in mT. - :param float x: ``x`` coordinate [nm] - :param float y: ``y`` coordinate [nm] - :param float z: ``z`` coordinate [nm] + :param float x: :math:`x` coordinate [nm] + :param float y: :math:`y` coordinate [nm] + :param float z: :math:`z` coordinate [nm] """ dx11, dx12 = x - self._range[0][0], x - self._range[0][1] @@ -382,14 +373,20 @@ def Bzx_method(self, x, y, z): def _bzx(dx1, dx2, dy1, dy2, dz1, dz2): """Calculate the summation term for magnetic field gradient. - Optimized with numba. See method bzx for the explanation. - - :param np.array dx1, dx2: distance between grid and the 2 ends of - magnet in x direction [nm] - :param np.array dy1, dy2: distance between grid and the 2 ends of - magnet in y direction [nm] - :param np.array dz1, dz2: distance between grid and the 2 ends of - magnet in z direction [nm] + Optimized with numba. See method ``Bzx_method`` for the explanation. + + :param float dx1: distance between grid and one end of magnet + in :math:`x` direction [nm] + :param float dx2: distance between grid and other end of magnet + in :math:`x` direction [nm] + :param float dy1: distance between grid and one end of magnet + in :math:`y` direction [nm] + :param float dy2: distance between grid and other end of magnet + in :math:`y` direction [nm] + :param float dz1: distance between grid and one end of magnet + in :math:`z` direction [nm] + :param float dz2: distance between grid and other end of magnet + in :math:`z` direction [nm] """ return ( @@ -404,18 +401,11 @@ def _bzx(dx1, dx2, dy1, dy2, dz1, dz2): ) def Bzxx_method(self, x, y, z): - r"""Calculate magnetic field second derivative :math:`B_{zxx}`/ - - Approxing Cylinder Magnet by 11 Rectangular Magnet. When viewed from the - vertical direction, we are using a row of rectangles to approximate a circle, - these rectangular blocks are arranged side by side, with the following lengths - and widths: - - (6,1)(10,1)(14,1)(16,2)(18,2)(20,6)(18,2)(16,2)(14,1)(10,1)(6,1) + r"""Calculate magnetic field second derivative :math:`B_{zxx}`. - This is arroximation for a circle with a diameter of 20, these shapes if found by - Minecraft community.The magnetic field is given by the sum of the magnetic fields - of these 11 rectangles. + Approximating Cylinder Magnet by 11 Rectangular Magnets. When viewed from the + vertical direction, we are using a row of rectangles to approximate a circle, + these rectangular blocks are arranged side by side. The magnetic field second derivative for RectangularMagnet is: :math:`B_{zxx} \equiv \partial^2 B_z / \partial x^2` @@ -423,7 +413,7 @@ def Bzxx_method(self, x, y, z): The magnetic field's second derivative is given by the following: .. math:: - B_{zxx} = \dfrac{\partial B_z}{\partial z} + B_{zxx} = \dfrac{\partial^2 B_z}{\partial x^2} = \dfrac{\mu_0 M_s}{4 \pi} \sum_{i=1}^2 \sum_{j=1}^2 \sum_{k=1}^2(-1)^{i+j+k} \left( \dfrac{-(x-x_i)(y-y_j)(z-z_k) @@ -432,9 +422,10 @@ def Bzxx_method(self, x, y, z): ((x-x_i)^2 + (z-z_k)^2)^2} \right) with the variables defined above. - :param float x: ``x`` coordinate [nm] - :param float y: ``y`` coordinate [nm] - :param float z: ``z`` coordinate [nm] + + :param float x: :math:`x` coordinate [nm] + :param float y: :math:`y` coordinate [nm] + :param float z: :math:`z` coordinate [nm] """ dx11, dx12 = x - self._range[0][0], x - self._range[0][1] @@ -513,13 +504,20 @@ def Bzxx_method(self, x, y, z): def _bzxx(dx1, dx2, dy1, dy2, dz1, dz2): """The summation term for the second derivative of magnetic field. - Optimized by numba. See bzxx method for the explanation. - :param float dx1, dx2: distance between grid and the one end of magnet - in x direction [nm] - :param float dy1, dy2: distance between grid and the one end of magnet - in y direction [nm] - :param float dz1, dz2: distance between grid and the one end of magnet - in z direction [nm] + Optimized by numba. See Bzxx_method for the explanation. + + :param float dx1: distance between grid and one end of magnet + in :math:`x` direction [nm] + :param float dx2: distance between grid and other end of magnet + in :math:`x` direction [nm] + :param float dy1: distance between grid and one end of magnet + in :math:`y` direction [nm] + :param float dy2: distance between grid and other end of magnet + in :math:`y` direction [nm] + :param float dz1: distance between grid and one end of magnet + in :math:`z` direction [nm] + :param float dz2: distance between grid and other end of magnet + in :math:`z` direction [nm] """ return ( @@ -564,5 +562,3 @@ def _bzxx(dx1, dx2, dy1, dy2, dz1, dz2): * (3.0 * dx2**2 + 2.0 * dy2**2 + 3.0 * dz2**2) / ((dx2**2 + dy2**2 + dz2**2) ** 1.5 * (dx2**2 + dz2**2) ** 2) ) - - \ No newline at end of file diff --git a/tests/test_component/test_cylindermagnet.py b/tests/test_component/test_cylindermagnet.py index addbcbf..e03cb89 100644 --- a/tests/test_component/test_cylindermagnet.py +++ b/tests/test_component/test_cylindermagnet.py @@ -17,16 +17,16 @@ Bz_method ^^^^^^^^^^ -1. Test Bz's output has the same shape as the input grid -2. Test Bz's output is symmetric along x-axis +1. Test Bz output has the same shape as the input grid +2. Test Bz output is symmetric along x-axis 3. Test Bz in the near field is close to the exact value 4. Test Bz in the far field is close to the exact value Bzx_method ^^^^^^^^^^ -1. Test Bzx's output has the same shape as the input grid -2. Test Bzx's output is symmetric along x-axis +1. Test Bzx output has the same shape as the input grid +2. Test Bzx output is symmetric along x-axis 3. Test Bzx in the near field is close to the exact value 4. Test Bzx in the far field is close to the exact value 5. Test Bzx when x is 0, Bzx is 0 @@ -34,8 +34,8 @@ Bzxx_method ^^^^^^^^^^^ -1. Test Bzxx's output has the same shape as the input grid -2. Test Bzxx's output is symmetric along x-axis +1. Test Bzxx output has the same shape as the input grid +2. Test Bzxx output is symmetric along x-axis 3. Test Bzxx in the near field is close to the exact value 4. Test Bzxx in the far field is close to the exact value """ @@ -85,7 +85,7 @@ def test_Bzxx_symmetry(self): def test_Bz_near_field(self): """Test the magnetic field Bz at near field. - + Test at poles (1.0, 2.0, 6.0). """ Bz = self.magnet.Bz_method(1, 2, 6) @@ -93,7 +93,7 @@ def test_Bz_near_field(self): def test_Bzx_near_field(self): """Test the magnetic field Bzx at near field. - + Test at poles (1.0, 2.0, 6.0). """ Bzx = self.magnet.Bzx_method(1, 2, 6) @@ -101,7 +101,7 @@ def test_Bzx_near_field(self): def test_Bzxx_near_field(self): """Test the magnetic field Bzxx at near field. - + Test at poles (1.0, 2.0, 6.0). """ Bzxx = self.magnet.Bzxx_method(1, 2, 6) @@ -109,7 +109,7 @@ def test_Bzxx_near_field(self): def test_Bz_far_field(self): """Test the magnetic field Bz at far field. - + Test at (10.0, 0.0, 0.0). """ Bz = self.magnet.Bz_method(10, 0, 0) @@ -117,7 +117,7 @@ def test_Bz_far_field(self): def test_Bzx_far_field(self): """Test the magnetic field Bzx at far field. - + Test at (10.0, 0.0, 0.0). """ Bzx = self.magnet.Bzx_method(10, 0, 0) @@ -125,7 +125,7 @@ def test_Bzx_far_field(self): def test_Bzxx_far_field(self): """Test the magnetic field Bzxx at far field. - + Test at (10.0, 0.0, 0.0). """ Bzxx = self.magnet.Bzxx_method(10, 0, 0) @@ -133,7 +133,7 @@ def test_Bzxx_far_field(self): def test_Bzx_x_is_0(self): """Test the magnetic field Bzx when x is 0. - + Test at (0.0, 10.0, 0.0). """ Bzx = self.magnet.Bzx_method(0, 10, 0) diff --git a/tests/test_formula/test_polarization.py b/tests/test_formula/test_polarization.py index 5c348c6..d504238 100644 --- a/tests/test_formula/test_polarization.py +++ b/tests/test_formula/test_polarization.py @@ -177,8 +177,11 @@ def test_rel_dpol_sat_td_symmetry(sample_e): ) assert np.array_equal(rpol_a, rpol_b) -def test_rel_dpol_sat_td_NaN(sample_e): - """Test rel_dpol_sat_td will not return Nan when Bzx is 0 and B_offset is symmetric. + +def test_rel_dpol_sat_td_nan(sample_e): + """Test rel_dpol_sat_td does not return nan. + + When Bzx is 0 and B_offset is symmetric, the result should not be nan. """ Bzx = np.array([1, 0, -1]) ext_B_offset_a = np.array([2, 0, 0, 0, 2]) From 678d5afde6f2226cabf2f2966f78ec0e9f281f5a Mon Sep 17 00:00:00 2001 From: Peter Sun Date: Thu, 30 Oct 2025 10:44:14 -0400 Subject: [PATCH 32/45] Add issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 57 +++++++++++++++ .github/ISSUE_TEMPLATE/config.yml | 6 ++ .github/ISSUE_TEMPLATE/documentation.md | 30 ++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 39 ++++++++++ .github/pull_request_template.md | 88 +++++++++++++++++++++++ 5 files changed, 220 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/documentation.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/pull_request_template.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..4395f95 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,57 @@ +--- +name: Bug Report +about: Create a report to help us improve +title: '[BUG] ' +labels: bug +assignees: '' +--- + +## Bug Description + + + +## Steps to Reproduce + + + +1. +2. +3. +4. + +## Expected Behavior + + + +## Actual Behavior + + + +## Environment + + + +- **OS:** [e.g., macOS 13.0, Ubuntu 22.04, Windows 11] +- **Python Version:** [e.g., 3.9.7, 3.10.5] +- **mrfmsim Version:** [e.g., 0.1.0, or commit hash if installed from source] +- **Installation Method:** [e.g., pip, conda, from source] + +## Error Messages/Stack Traces + + + +``` +Paste error message here +``` + +## Additional Context + + + +## Possible Solution + + diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..15216c1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,6 @@ +blank_issues_enabled: true +contact_links: + - name: Questions and Discussions + url: https://github.com/Marohn-Group/mrfmsim/discussions + about: Ask questions and discuss ideas with the community + diff --git a/.github/ISSUE_TEMPLATE/documentation.md b/.github/ISSUE_TEMPLATE/documentation.md new file mode 100644 index 0000000..01cd403 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/documentation.md @@ -0,0 +1,30 @@ +--- +name: Documentation Issue +about: Report an issue with documentation +title: '[DOCS] ' +labels: documentation +assignees: '' +--- + +## Documentation Issue + + + +## Location + + + +## Current Documentation + + + +## Suggested Improvement + + + +## Additional Context + + + + + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..eb02e42 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,39 @@ +--- +name: Feature Request +about: Suggest an idea for this project +title: '[FEATURE] ' +labels: enhancement +assignees: '' +--- + +## Feature Description + + + +## Problem/Motivation + + + +## Proposed Solution + + + +## Alternative Solutions + + + +## Use Case + + + +## Additional Context + + + +## Potential Implementation + + + + + diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..eeaf923 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,88 @@ +## Type of Pull Request + + + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to change) +- [ ] Documentation update +- [ ] Code refactoring +- [ ] Performance improvement +- [ ] Test coverage improvement +- [ ] Other (please describe): + +## Description + + + + +## Related Issue(s) + + + + + +## Changes Made + + + +- +- +- + +## Breaking Changes + + + + + +## Testing Performed + + + +- [ ] All existing tests pass (`tox` or `pytest`) +- [ ] Added new tests for new functionality +- [ ] Manual testing performed (describe below) + +### Test Details + + + + +## Documentation + + + +- [ ] Updated docstrings for new/modified functions and classes +- [ ] Updated relevant documentation files (if applicable) +- [ ] Added usage examples (if applicable) +- [ ] Documentation builds without errors (`cd docs && make html`) + +## Code Quality + + + +- [ ] Code follows PEP 8 style guidelines +- [ ] Used meaningful variable and function names +- [ ] Code is modular and readable + +## Checklist + + + +- [ ] My code follows the project's coding standards +- [ ] I have performed a self-review of my own code +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] My changes generate no new warnings or errors +- [ ] I have checked that this PR focuses on a single feature or bug fix + +## Additional Notes + + + + +## Screenshots (if applicable) + + + + From fd79a9a823cc54b72a655381b20574514f928613 Mon Sep 17 00:00:00 2001 From: Peter Sun Date: Thu, 30 Oct 2025 10:44:29 -0400 Subject: [PATCH 33/45] Add contribution guidelines --- README.rst | 5 ++ docs/contribute.rst | 158 ++++++++++++++++++++++++++++++++++++++++++++ docs/index.rst | 1 + 3 files changed, 164 insertions(+) create mode 100644 docs/contribute.rst diff --git a/README.rst b/README.rst index 73ca6fc..01f5eef 100644 --- a/README.rst +++ b/README.rst @@ -65,6 +65,11 @@ To test in different environments:: tox +Contributing +^^^^^^^^^^^^ + +We welcome contributions! Please see our `Contributing Guide `_ for details on how to follow our development guidelines and submit pull requests. + .. rubric:: References .. [#Sidles1995jan] Sidles, J. A.; Garbini, J. J.; Bruland, K. J.; Rugar, D.; diff --git a/docs/contribute.rst b/docs/contribute.rst new file mode 100644 index 0000000..cac76a4 --- /dev/null +++ b/docs/contribute.rst @@ -0,0 +1,158 @@ +Contribute +======================== + +We welcome contributions to mrfmsim! This guide will help you get started. + +Getting Started +--------------- + +1. **Fork the Repository** + + Fork the mrfmsim repository on GitHub and clone your fork locally: + + .. code-block:: bash + + git clone https://github.com/Marohn-Group/mrfmsim.git + cd mrfmsim + + +2. **Create a Branch** + + Create a new branch for your feature or bug fix: + + .. code-block:: bash + + git checkout -b feature/your-branch-name + +Development Guidelines +---------------------- + +Code Style +~~~~~~~~~~ + +- Follow PEP 8 style guidelines for Python code +- Use meaningful variable and function names +- Keep functions focused and modular +- Add type hints where appropriate + +Documentation +~~~~~~~~~~~~~ + +- Write clear docstrings for all public classes, methods, and functions +- Use reStructuredText (reST) format for docstrings +- Refer to the `Sphinx docstring guide `__ for detailed formatting information +- Include: + + - Brief description of what the function/class does + - Parameter descriptions with types and units in **Sphinx** docstring format + - Return value description + - Usage examples where helpful + - Mathematical formulas using Sphinx math directive when relevant + +Example docstring format: + +.. code-block:: python + + def example_method(x, y, z): + r"""Calculate some property. + + Brief description of what this method does and any important + details about the calculation or algorithm. + + :param float x: :math:`x` coordinate [nm] + :param float y: :math:`y` coordinate [nm] + :param float z: :math:`z` coordinate [nm] + :return: calculated value + :rtype: float + """ + pass + + +Building Documentation +---------------------- + +To build the documentation locally: + +.. code-block:: bash + + cd docs + make html + +The built documentation will be in ``docs/_build/html/``. + +Testing +~~~~~~~ + +- Write tests for all new features and bug fixes +- Tests should be fast and independent from one another +- Ensure all tests pass before submitting a pull request +- Aim for good test coverage of your code + +Install test dependencies: + +.. code-block:: bash + + pip install ".[test]" + +Run tests with tox: + +.. code-block:: bash + + tox + +This will run tests across multiple Python environments and check code coverage. + + +Submitting a Pull Request +-------------------------- + +**Important**: Each pull request should focus on a single feature or bug fix. This makes the code easier to review, test, and maintain. + +1. **Push to Your Fork** + + .. code-block:: bash + + git push origin feature/your-feature-name + +2. **Create Pull Request** + + - Go to the mrfmsim repository on GitHub + - Click "New Pull Request" + - Select your fork and the ``develop`` branch as the base branch + - Fill out the pull request template with: + + - Type of pull request (bug fix, feature, documentation, etc.) + - Description of changes + - Related issue numbers (if applicable) + - Any breaking changes + - Testing performed + +3. **Review Process** + + - Maintainers will review your pull request + - Address any feedback or requested changes + - Once approved, your changes will be merged + + +Reporting Issues +---------------- + +When reporting issues, please include: + +- A clear description of the problem +- Steps to reproduce the issue +- Expected vs. actual behavior +- Your environment (Python version, OS, etc.) +- Any relevant error messages or stack traces + +Questions? +---------- + +If you have questions about contributing, feel free to: + +- Open an issue on GitHub +- Check existing documentation +- Reach out to the maintainers + +Thank you for contributing to mrfmsim! + diff --git a/docs/index.rst b/docs/index.rst index bd48edc..8610f65 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -15,6 +15,7 @@ License overview tests changelog + contribute .. toctree:: From 7958099ede6610cce6fd32e4a876639e77cd25a6 Mon Sep 17 00:00:00 2001 From: Peter Sun Date: Thu, 30 Oct 2025 11:06:03 -0400 Subject: [PATCH 34/45] Add formatter guideline --- .github/pull_request_template.md | 4 ++-- docs/contribute.rst | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index eeaf923..cfb96b5 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -40,7 +40,7 @@ -- [ ] All existing tests pass (`tox` or `pytest`) +- [ ] All existing tests pass (`tox`) - [ ] Added new tests for new functionality - [ ] Manual testing performed (describe below) @@ -62,7 +62,7 @@ -- [ ] Code follows PEP 8 style guidelines +- [ ] Code follows PEP 8 style guidelines (use ``Black`` formatter's default settings) - [ ] Used meaningful variable and function names - [ ] Code is modular and readable diff --git a/docs/contribute.rst b/docs/contribute.rst index cac76a4..9daa7b4 100644 --- a/docs/contribute.rst +++ b/docs/contribute.rst @@ -30,7 +30,7 @@ Development Guidelines Code Style ~~~~~~~~~~ -- Follow PEP 8 style guidelines for Python code +- Follow PEP 8 style guidelines for Python code (use ``Black`` formatter's default settings) - Use meaningful variable and function names - Keep functions focused and modular - Add type hints where appropriate From eacbef4f1557df040c0ed419e0a310e41e8f15c8 Mon Sep 17 00:00:00 2001 From: Peter Sun Date: Thu, 30 Oct 2025 11:09:32 -0400 Subject: [PATCH 35/45] Remove sympy --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7908d6d..fa54b2d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,6 @@ numpy = ">=1.26.4" mmodel = { git = "https://www.github.com/Marohn-Group/mmodel.git", branch = "develop-0.8.1" } numba = ">=0.60.0" scipy = ">=1.14.1" -sympy = ">=1.13.3" tox = { version = ">=3.25.0", optional = true } tox-conda = { version = ">=0.9.2", optional = true } pytest = { version = ">=7.1.1", optional = true } From 9c5966f26feaaa274128ed95a2410590b8b1b608 Mon Sep 17 00:00:00 2001 From: Peter Sun Date: Thu, 30 Oct 2025 11:17:21 -0400 Subject: [PATCH 36/45] Adjust the td cermit polarization behavior --- mrfmsim/formula/polarization.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/mrfmsim/formula/polarization.py b/mrfmsim/formula/polarization.py index 900a63a..ae2b1b2 100644 --- a/mrfmsim/formula/polarization.py +++ b/mrfmsim/formula/polarization.py @@ -2,8 +2,7 @@ # -*- coding: utf-8 -*- # Peter Sun -"""Collection of calculations of relative changes in polarization. -""" +"""Collection of calculations of relative changes in polarization.""" import numba import numpy as np @@ -244,11 +243,9 @@ def rel_dpol_sat_td(Bzx, B1, ext_B_offset, ext_pts, Gamma, T2, tip_v): div = np.divide(atan_omega_f - atan_omega_i, Bzx) - # adjust for the center slice of the discontinuous issue - nan_indices = np.where(np.isnan(div))[0] - unique_nan_indices = list(set(nan_indices)) - for i in unique_nan_indices: - div[i] = (div[i + 1]+div[i - 1])/2 + # adjust the nan values to the average of the surrounding values + for idx in np.where(np.isnan(div))[0]: + div[idx] = (div[idx + 1] + div[idx - 1]) / 2 rt = Gamma * B1**2 * np.abs(div) / tip_v dpol = np.exp(-rt) @@ -288,4 +285,4 @@ def rel_dpol_multipulse(rel_dpol, T1, dt_pulse): t_r = dt_pulse / T1 rel_dpol_avg = (np.exp(t_r) - 1) * rel_dpol / t_r / (np.exp(t_r) - pol) - return rel_dpol_avg \ No newline at end of file + return rel_dpol_avg From e5ce9d1d0bf60c9c481793b9a6186c960fa6ab16 Mon Sep 17 00:00:00 2001 From: Peter Sun Date: Thu, 30 Oct 2025 11:20:46 -0400 Subject: [PATCH 37/45] Revert the changes to magnet.py --- mrfmsim/component/magnet.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/mrfmsim/component/magnet.py b/mrfmsim/component/magnet.py index 868ca74..b0d3275 100644 --- a/mrfmsim/component/magnet.py +++ b/mrfmsim/component/magnet.py @@ -4,7 +4,6 @@ from mrfmsim.component import ComponentBase - @dataclass class SphereMagnet(ComponentBase): """Spherical magnet object with its Bz, Bzx, Bzxx calculations. @@ -457,6 +456,3 @@ def _bzxx(dx1, dx2, dy1, dy2, dz1, dz2): * (3.0 * dx2**2 + 2.0 * dy2**2 + 3.0 * dz2**2) / ((dx2**2 + dy2**2 + dz2**2) ** 1.5 * (dx2**2 + dz2**2) ** 2) ) - - - From 992fc16203ab4d8801f7beafcea62a38a46bf271 Mon Sep 17 00:00:00 2001 From: Peter Sun Date: Thu, 30 Oct 2025 12:00:36 -0400 Subject: [PATCH 38/45] Documentation and docstring format change --- docs/basic/geometry.rst | 4 +- docs/basic/inheritance.rst | 2 +- docs/basic/plugin.rst | 4 +- docs/experiment/CermitSat.rst | 2 +- docs/experiment/CermitSingleSpin.rst | 2 +- docs/experiment/CermitTD.rst | 2 +- docs/experiment/IBMCyclic.rst | 2 +- docs/overview.rst | 6 +- docs/reference/ref_magnetization.rst | 2 +- docs/setup/cantilever.rst | 4 +- docs/setup/coordinates.rst | 4 +- docs/setup/grid.rst | 4 +- docs/tests.rst | 6 +- mrfmsim/component/cantilever.py | 2 +- mrfmsim/component/grid.py | 6 +- mrfmsim/component/magnet.py | 181 ++++++++++++++++----------- mrfmsim/component/sample.py | 6 +- mrfmsim/formula/field.py | 2 +- mrfmsim/formula/magnetization.py | 14 +-- mrfmsim/formula/misc.py | 21 ++-- 20 files changed, 157 insertions(+), 119 deletions(-) diff --git a/docs/basic/geometry.rst b/docs/basic/geometry.rst index c7d0e5e..757a4c4 100644 --- a/docs/basic/geometry.rst +++ b/docs/basic/geometry.rst @@ -1,9 +1,9 @@ Experiment geometry ============================= -For experiments in the *mrfmsim*, two experimental geometry +For experiments in the *mrfmsim*, two experimental geometries are used: "hangdown" and SPAM (springiness preservation by aligning magnetization). -The two geometry are shown in the figure below. +The two geometries are shown in the figure below. .. image:: ../_static/mrfm-setups.pdf :width: 800px diff --git a/docs/basic/inheritance.rst b/docs/basic/inheritance.rst index 8768778..e2514b2 100644 --- a/docs/basic/inheritance.rst +++ b/docs/basic/inheritance.rst @@ -67,5 +67,5 @@ ExperimentGroup ---------------- The ``mrfmsim.group.ExperimentGroup`` class adds additional properties -``epxeriments`` and ``epxeriment_defaults`` alongside the parent class's +``experiments`` and ``experiment_defaults`` alongside the parent class's ``models`` and ``model_defaults`` properties. diff --git a/docs/basic/plugin.rst b/docs/basic/plugin.rst index c5882a9..9d04ed7 100644 --- a/docs/basic/plugin.rst +++ b/docs/basic/plugin.rst @@ -5,13 +5,13 @@ Ancillary features are added to the mrfmsim ecosystem through plugin packages. The separation of the core functionality and the plugins allows for an easy maintenance of the mrfmsim package. The core functionalities do not depend on the plugins. -mrfmsim-ymal: YAML configuration plugin +mrfmsim-yaml: YAML configuration plugin --------------------------------------- mrfmsim classes can be fully defined using YAML configuration files. The plugin creates a ``MrfmSimLoader`` and a ``MrfmSimDumper`` that can be used to load and dump the mrfmsim classes to and from YAML files. For detailed usage of the package -see the `mrfmsim-ymal `_. +see the `mrfmsim-yaml `_. To define an experiment or experiment group with YAML files, the available tags are: "!func", "!import", "!nodes", "!Graph", "!Experiment", and "!ExperimentGroup". diff --git a/docs/experiment/CermitSat.rst b/docs/experiment/CermitSat.rst index df868c5..db2e26d 100644 --- a/docs/experiment/CermitSat.rst +++ b/docs/experiment/CermitSat.rst @@ -101,7 +101,7 @@ in the Table below. ======================================== ================================================= Variables appearing in eqs. :eq:`eq:x`, :eq:`eq:x-vars`, and subsequent equations. -he magnetic field :math:`B_0` is applied along the :math:`z` axis, +The magnetic field :math:`B_0` is applied along the :math:`z` axis, and the equilibrium magnetization :math:`M_0` also lies along the :math:`z` axis. Steady-state solution diff --git a/docs/experiment/CermitSingleSpin.rst b/docs/experiment/CermitSingleSpin.rst index 44109e1..7748f12 100644 --- a/docs/experiment/CermitSingleSpin.rst +++ b/docs/experiment/CermitSingleSpin.rst @@ -5,7 +5,7 @@ Overview -------- The experiments calculate the effective force on a cantilever from a single electron spin located directly below a magnet-tipped cantilever in the "hangdown" and SPAM geometries. -There are two experiments in the group: cantilever spin constant shift calculated using the Trapezoid rule ("CermitSingleSpinApprox"), and cantilever spring constant shift calculated directly using elliptic integrals ("CermitSingleSpin"). +There are two experiments in the group: cantilever spring constant shift calculated using the Trapezoid rule ("CermitSingleSpinApprox"), and cantilever spring constant shift calculated directly using elliptic integrals ("CermitSingleSpin"). The exact solution only works for spin directly under a **spherical** magnet. The experiments are adopted from Section 3.5 of Eric Moore's dissertation. [#Moore2011Sep]_ diff --git a/docs/experiment/CermitTD.rst b/docs/experiment/CermitTD.rst index 1bcf269..0d19972 100644 --- a/docs/experiment/CermitTD.rst +++ b/docs/experiment/CermitTD.rst @@ -26,7 +26,7 @@ At low-:math:`B_1` region, we can determine numerically the final magnetization .. math:: :label: eq:Mz(tau0) - M_z^\mathrm{finial} + M_z^\mathrm{final} \approx e^{-R(\tau_i, \tau_f)} M_z^\mathrm{initial} diff --git a/docs/experiment/IBMCyclic.rst b/docs/experiment/IBMCyclic.rst index 2f2bc54..8c85896 100644 --- a/docs/experiment/IBMCyclic.rst +++ b/docs/experiment/IBMCyclic.rst @@ -34,7 +34,7 @@ as the MRFM signal. For :math:`n` independent configurations of the spin ensembl the sample variance :math:`s^2_{\Delta N}` is .. math:: - s^2_{\Delta N} = \frac{1}{n-1} \sum^n_{j=1} (\Delta N_j - \overline{\Delta N}) + s^2_{\Delta N} = \frac{1}{n-1} \sum^n_{j=1} (\Delta N_j - \overline{\Delta N})^2 where :math:`\overline{\Delta N}` is the Boltzmann polarization. diff --git a/docs/overview.rst b/docs/overview.rst index 3403598..70f97d7 100644 --- a/docs/overview.rst +++ b/docs/overview.rst @@ -93,7 +93,7 @@ To access an experiment model from a experiment group: .. code:: python - # print c summary + # print a summary print(CermitESRGroup) # list experiments print(list(CermitESRGroup.experiments.keys())) @@ -184,7 +184,7 @@ can be very computationally intensive. If we want to simulate the change of the signal over a wide range of external field (:math:`B_0`) and microwave frequency -(:math:`f_\mathrm{rf}``), we would want to avoid repeated +(:math:`f_\mathrm{rf}`), we would want to avoid repeated calculations of unnecessary components that are independent of the two parameters. @@ -263,7 +263,7 @@ This is equivalent to the result from the following loops: .. note:: - Note that for individual parameters, the loop shortcut can achieve + For individual parameters, the loop shortcut can achieve optimal looping. However, for multiple parameters, users must decide which parameter to loop first. Since all nodes that are dependent on "f_rf" also depend on "B_0", we loop "f_rf" first. diff --git a/docs/reference/ref_magnetization.rst b/docs/reference/ref_magnetization.rst index 5f0e851..2b449e9 100644 --- a/docs/reference/ref_magnetization.rst +++ b/docs/reference/ref_magnetization.rst @@ -43,7 +43,7 @@ the equilibrium magnetization tends towards the Curie-Weiss law, .. math:: - mu_z^{\text{eq}} + \mu_z^{\text{eq}} \approx \dfrac{\hbar^2 \gamma^2 \: J (J + 1)}{3 \: k_b T} B_0 diff --git a/docs/setup/cantilever.rst b/docs/setup/cantilever.rst index 9c78698..f81836d 100644 --- a/docs/setup/cantilever.rst +++ b/docs/setup/cantilever.rst @@ -9,11 +9,11 @@ Example Usage ^^^^^^^^^^^^^ Create a cantilever object with a spring constant of 780 aN/nm and -frequency of 4795 Hz: +frequency of 4975 Hz: .. code-block:: python - cantilever = Cantilever(k_c=780, f_c=4795) + cantilever = Cantilever(k_c=780, f_c=4975) To print out the cantilever summary: diff --git a/docs/setup/coordinates.rst b/docs/setup/coordinates.rst index 7b1f79b..ab740a2 100644 --- a/docs/setup/coordinates.rst +++ b/docs/setup/coordinates.rst @@ -39,8 +39,8 @@ With the right figure setup, magnet = RectangularMagnet([70, 70, 1500], mu0_Ms=1800.0, magnet_origin=[0.0, 750.0, 0.0]) The grid has a width of 220 nm in :math:`y`-direction, and the magnet has a height of -1500 nm. The grid origin is set to be 110 nm below left of the :math:`xz`-plane, -and the magnet origin is set to be 750 nm right to the :math:`xz`-plane. The magnet and the +1500 nm. The grid origin is set to be 110 nm to the left of the :math:`xz`-plane, +and the magnet origin is set to be 750 nm to the right of the :math:`xz`-plane. The magnet and the grid are flush, and the tip-sample separation is 0 nm. .. note:: diff --git a/docs/setup/grid.rst b/docs/setup/grid.rst index 2ca0483..66f3693 100644 --- a/docs/setup/grid.rst +++ b/docs/setup/grid.rst @@ -14,8 +14,8 @@ To create a grid object: grid = Grid(grid_shape=[21, 11, 101], grid_step=[20.0, 4.0, 20.0], grid_origin=[0.0, 0.0, 0.0]) The resulting grid is rectangular with the shape of (21, 11, 101), the distance between -two edge grid points in each direction are (200, 40, 2000) nm, and the full grid size -is (220 :math:`\times` 44 :math:`\times` 2020) nm. +two edge grid points in each direction are (400, 40, 2000) nm, and the full grid size +is (420 :math:`\times` 44 :math:`\times` 2020) nm. The returned grid points are numpy "ogrid" points: `np.ogrid `__. diff --git a/docs/tests.rst b/docs/tests.rst index 641996b..f553cad 100644 --- a/docs/tests.rst +++ b/docs/tests.rst @@ -36,8 +36,8 @@ Magnet Test The RectMagnet is tested through its symmetry factors: it is symmetric in the :math:`z` direction when x and y are 0. The gradient functions are tested against a numerical derivative calculation from the field. :math:`B_z` is an even function in the :math:`x` direction, -:math:`B_{zx}` is an odd function in the x-direction and -:math: `B_{zxx}` is an even function in the :math:`x` direction. +:math:`B_{zx}` is an odd function in the :math:`x` direction, and +:math:`B_{zxx}` is an even function in the :math:`x` direction. Polarization Test @@ -68,7 +68,7 @@ Note to see the notebook and examples go to the the effect of amplitude is also small (There is a comparison in "test-micrometertip_smallampapprox_vs_exactsol.ipynb" on small amplitude, however, the result is unchecked). -- CmeritSingleSpinESR_Approx is compared with CermitARP_SmallTip. +- CermitSingleSpinESR_Approx is compared with CermitARP_SmallTip. - SingleSpinESR - The approximation is tested against both SPAM and hangdown geometry of the analytical solution diff --git a/mrfmsim/component/cantilever.py b/mrfmsim/component/cantilever.py index a04bfce..2d8c02c 100644 --- a/mrfmsim/component/cantilever.py +++ b/mrfmsim/component/cantilever.py @@ -14,7 +14,7 @@ class Cantilever(ComponentBase): :param float f_c: mechanical resonance frequency [Hz] :ivar float k2f_modulated: spring constant to frequency ratio for modulated - cantilever (lockin) [Hz.nm/aN]p + cantilever (lockin) [Hz.nm/aN] :ivar float k2f: spring constant to frequency ratio for non-modulated cantilever [Hz.nm/aN] """ diff --git a/mrfmsim/component/grid.py b/mrfmsim/component/grid.py index 963b184..eb18d17 100644 --- a/mrfmsim/component/grid.py +++ b/mrfmsim/component/grid.py @@ -14,10 +14,10 @@ class Grid(ComponentBase): The grid array uses numpy's open mesh-grid, which has speed and storage benefits. - :param tuple[int] shape: grid dimension + :param tuple[int, int, int] grid_shape: grid dimension (number of points in x, y, z direction) - :param ndarray grid_step: grid setup size in x, y, z direction - :param ndarray grid_origin: the grid origin + :param list[float] grid_step: grid step size in x, y, z direction [nm] + :param list[float] grid_origin: the grid origin [nm] :ivar ndarray grid_length: array of lengths along (x, y, z) :ivar float grid_voxel: the volume of each grid voxel diff --git a/mrfmsim/component/magnet.py b/mrfmsim/component/magnet.py index b0d3275..c0b403a 100644 --- a/mrfmsim/component/magnet.py +++ b/mrfmsim/component/magnet.py @@ -9,7 +9,8 @@ class SphereMagnet(ComponentBase): """Spherical magnet object with its Bz, Bzx, Bzxx calculations. :param float magnet_radius: sphere magnet radius [nm] - :param list magnet_origin: the position of the magnet origin (x, y, z) + :param list magnet_origin: the position of the magnet origin + :math:`(x, y, z)` [nm] :param float mu0_Ms: saturation magnetization [mT] """ @@ -20,9 +21,9 @@ class SphereMagnet(ComponentBase): def Bz_method(self, x, y, z): r"""Calculate magnetic field :math:`B_z` [mT]. - :param float x: x coordinate of sample grid [nm] - :param float y: y coordinate of sample grid [nm] - :param float z: z coordinate of sample grid [nm] + :param float x: :math:`x` coordinate of sample grid [nm] + :param float y: :math:`y` coordinate of sample grid [nm] + :param float z: :math:`z` coordinate of sample grid [nm] The magnetic field is calculated as @@ -57,12 +58,15 @@ def Bz_method(self, x, y, z): def _bz(dx, dy, dz): """Internal calculation for bz, optimized with numba. - :param dx: normalized distances to the center of the magnet in x - :param dx: normalized distances to the center of the magnet in y - :param dx: normalized distances to the center of the magnet in z + :param float dx: normalized distances to the center of the magnet in + :math:`x` direction [nm] + :param float dy: normalized distances to the center of the magnet in + :math:`y` direction [nm] + :param float dz: normalized distances to the center of the magnet in + :math:`z` direction [nm] :return: bz without pre-term - :rtype: np.array + :rtype: float """ return ( @@ -80,14 +84,14 @@ def Bzx_method(self, x, y, z): gradient is calculated as .. math:: - B_{zx} = \dfrac{\partial B_z}{\partial z} + B_{zx} = \dfrac{\partial B_z}{\partial x} = \dfrac{\mu_0 M_s}{r} X \: \left( \dfrac{1}{R^5} - 5 \dfrac{Z^2}{R^7} \right) R = \sqrt{X^2+Y^2+Z^2} - :param float x: x coordinate of sample grid [nm] - :param float y: y coordinate of sample grid [nm] - :param float z: z coordinate of sample grid [nm] + :param float x: :math:`x` coordinate of sample grid [nm] + :param float y: :math:`y` coordinate of sample grid [nm] + :param float z: :math:`z` coordinate of sample grid [nm] :return: magnetic field gradient :rtype: np.array """ @@ -108,12 +112,15 @@ def Bzx_method(self, x, y, z): def _bzx(dx, dy, dz): """Internal calculation for bzx, optimized with numba. - :param dx: normalized distances to the center of the magnet in x - :param dy: normalized distances to the center of the magnet in y - :param dz: normalized distances to the center of the magnet in z + :param float dx: normalized distances to the center of the magnet in + :math:`x` direction [nm] + :param float dy: normalized distances to the center of the magnet in + :math:`y` direction [nm] + :param float dz: normalized distances to the center of the magnet in + :math:`z` direction [nm] :return: bzx without pre-term - :rtype: np.array + :rtype: float """ return dx * ( @@ -131,15 +138,15 @@ def Bzxx_method(self, x, y, z): second derivative is calculated as .. math:: - B_{zxx} = \dfrac{\partial B_z}{\partial z} + B_{zxx} = \dfrac{\partial^2 B_z}{\partial x^2} = \dfrac{\mu_0 M_s}{r^2} \: \left( \dfrac{1}{R^5} - 5 \dfrac{X^2}{R^7} - 5 \dfrac{Z^2}{R^7} + 35 \dfrac{X^2 Z^2}{R^9} \right) R = \sqrt{X^2+Y^2+Z^2} - :param float x: x coordinate of sample grid [nm] - :param float y: y coordinate of sample grid [nm] - :param float z: z coordinate of sample grid [nm] + :param float x: :math:`x` coordinate of sample grid [nm] + :param float y: :math:`y` coordinate of sample grid [nm] + :param float z: :math:`z` coordinate of sample grid [nm] :return: magnetic field second derivative :rtype: np.array """ @@ -160,12 +167,15 @@ def Bzxx_method(self, x, y, z): def _bzxx(dx, dy, dz): """Internal calculation for bzxx, optimized with numba. - :param dx: normalized distances to the center of the magnet in x - :param dy: normalized distances to the center of the magnet in y - :param dz: normalized distances to the center of the magnet in z + :param float dx: normalized distances to the center of the magnet in + :math:`x` direction [nm] + :param float dy: normalized distances to the center of the magnet in + :math:`y` direction [nm] + :param float dz: normalized distances to the center of the magnet in + :math:`z` direction [nm] :return: bzxx without pre-term - :rtype: np.array + :rtype: float """ return ( @@ -180,8 +190,10 @@ def _bzxx(dx, dy, dz): class RectangularMagnet(ComponentBase): """Rectangular magnet object with the bz, bzx, bzxx calculations. - :param list magnet_length: length of rectangular magnet in (x, y, z) direction [nm] - :param list magnet_origin: the position of the magnet origin (x, y, z) + :param list magnet_length: length of rectangular magnet in + :math:`(x, y, z)` direction [nm] + :param list magnet_origin: the position of the magnet origin + :math:`(x, y, z)` [nm] :param float mu0_Ms: saturation magnetization [mT] """ @@ -201,11 +213,18 @@ def __post_init__(self): def Bz_method(self, x, y, z): r"""Calculate magnetic field :math:`B_z` [mT]. - The magnetic field is calculated following Ravaud2009. + The magnetic field is calculated following Ravaud2009 [1]_. + + The magnet is set up so that the + :math:`x` and :math:`y` dimensions are centered about the zero point. + The translation in :math:`z` shifts the tip of the magnet in the + :math:`z`-direction to be the given distance from the surface. + Using the Coulombian model, assuming a uniform magnetization throughout the volume of the magnet and modeling each face of the magnet as a layer of continuous current density. The total field is found by summing over the faces. + The magnetic field is given by: .. math:: @@ -215,29 +234,24 @@ def Bz_method(self, x, y, z): Here :math:`(x,y,z)` are the coordinates for the location at which we want to know the field; - The magnet spans from x1 to x2 in the ``x``-direction, - y1 to y2 in the ``y``-direction, and z1 to z2 in - the ``z``-direction; + The magnet spans from x1 to x2 in the :math:`x`-direction, + y1 to y2 in the :math:`y`-direction, and z1 to z2 in + the :math:`z`-direction; .. math:: R = \sqrt{(x - x_i)^2 + (y - y_j)^2 + (z - z_k)^2} where :math:`\mu_0 M_s` is the magnet's saturation magnetization in mT. - **Reference**: - Ravaud, R. and Lemarquand, G. "Magnetic field produced by a - parallelepipedic magnet of various and uniform polarization" , - *PIER*, **2009**, *98*, 207-219 - [`10.2528/PIER09091704 `__]. + .. [1] Ravaud, R. and Lemarquand, G. "Magnetic field produced by a + parallelepipedic magnet of various and uniform polarization" , + *PIER*, **2009**, *98*, 207-219 + [`10.2528/PIER09091704 `__]. - - set the magnet up so that the x and y dimensions are centered about - the zero point. - - The translation in z should shift the tip of the magnet in the - z-direction to be the given distance from the surface. - :param float x: x coordinate of sample grid [nm] - :param float y: y coordinate of sample grid [nm] - :param float z: z coordinate of sample grid [nm] + :param float x: :math:`x` coordinate of sample grid [nm] + :param float y: :math:`y` coordinate of sample grid [nm] + :param float z: :math:`z` coordinate of sample grid [nm] """ dx1, dx2 = x - self._range[0], x - self._range[1] @@ -264,13 +278,20 @@ def Bz_method(self, x, y, z): def _bz(dx1, dx2, dy1, dy2, dz1, dz2): """Calculate the summation term for magnetic field optimized by numba. - See method bz for the explanation. - :param float dx1, dx2: distance between grid and the one end of magnet - in x direction [nm] - :param float dy1, dy2: distance between grid and the one end of magnet - in y direction [nm] - :param float dz1, dz2: distance between grid and the one end of magnet - in z direction [nm] + See method Bz_method for the explanation. + + :param float dx1: distance between grid and one end of magnet in + :math:`x` direction [nm] + :param float dx2: distance between grid and other end of magnet in + :math:`x` direction [nm] + :param float dy1: distance between grid and one end of magnet in + :math:`y` direction [nm] + :param float dy2: distance between grid and other end of magnet in + :math:`y` direction [nm] + :param float dz1: distance between grid and one end of magnet in + :math:`z` direction [nm] + :param float dz2: distance between grid and other end of magnet in + :math:`z` direction [nm] """ return ( @@ -305,13 +326,13 @@ def Bzx_method(self, x, y, z): from z1 to z2 in the ``z``-direction; .. math:: - R = \sqrt{(x - x_i) + (y - y_j) + (z - z_k)} + R = \sqrt{(x - x_i)^2 + (y - y_j)^2 + (z - z_k)^2} :math:`\mu_0 M_s` is the magnet's saturation magnetization in mT. - :param float x: ``x`` coordinate [nm] - :param float y: ``y`` coordinate [nm] - :param float z: ``z`` coordinate [nm] + :param float x: :math:`x` coordinate [nm] + :param float y: :math:`y` coordinate [nm] + :param float z: :math:`z` coordinate [nm] """ dx1, dx2 = x - self._range[0], x - self._range[1] @@ -338,14 +359,20 @@ def Bzx_method(self, x, y, z): def _bzx(dx1, dx2, dy1, dy2, dz1, dz2): """Calculate the summation term for magnetic field gradient. - Optimized with numba. See method bzx for the explanation. - - :param np.array dx1, dx2: distance between grid and the 2 ends of - magnet in x direction [nm] - :param np.array dy1, dy2: distance between grid and the 2 ends of - magnet in y direction [nm] - :param np.array dz1, dz2: distance between grid and the 2 ends of - magnet in z direction [nm] + Optimized with numba. See method Bzx_method for the explanation. + + :param float dx1: distance between grid and one end of magnet in + :math:`x` direction [nm] + :param float dx2: distance between grid and other end of magnet in + :math:`x` direction [nm] + :param float dy1: distance between grid and one end of magnet in + :math:`y` direction [nm] + :param float dy2: distance between grid and other end of magnet in + :math:`y` direction [nm] + :param float dz1: distance between grid and one end of magnet in + :math:`z` direction [nm] + :param float dz2: distance between grid and other end of magnet in + :math:`z` direction [nm] """ return ( @@ -360,14 +387,14 @@ def _bzx(dx1, dx2, dy1, dy2, dz1, dz2): ) def Bzxx_method(self, x, y, z): - r"""Calculate magnetic field second derivative :math:`B_{zxx}`/ + r"""Calculate magnetic field second derivative :math:`B_{zxx}`. :math:`B_{zxx} \equiv \partial^2 B_z / \partial x^2` [ :math:`\mathrm{mT} \; \mathrm{nm}^{-2}`] The magnetic field's second derivative is given by the following: .. math:: - B_{zxx} = \dfrac{\partial B_z}{\partial z} + B_{zxx} = \dfrac{\partial^2 B_z}{\partial x^2} = \dfrac{\mu_0 M_s}{4 \pi} \sum_{i=1}^2 \sum_{j=1}^2 \sum_{k=1}^2(-1)^{i+j+k} \left( \dfrac{-(x-x_i)(y-y_j)(z-z_k) @@ -376,9 +403,10 @@ def Bzxx_method(self, x, y, z): ((x-x_i)^2 + (z-z_k)^2)^2} \right) with the variables defined above. - :param float x: ``x`` coordinate [nm] - :param float y: ``y`` coordinate [nm] - :param float z: ``z`` coordinate [nm] + + :param float x: :math:`x` coordinate [nm] + :param float y: :math:`y` coordinate [nm] + :param float z: :math:`z` coordinate [nm] """ dx1, dx2 = x - self._range[0], x - self._range[1] @@ -405,13 +433,20 @@ def Bzxx_method(self, x, y, z): def _bzxx(dx1, dx2, dy1, dy2, dz1, dz2): """The summation term for the second derivative of magnetic field. - Optimized by numba. See bzxx method for the explanation. - :param float dx1, dx2: distance between grid and the one end of magnet - in x direction [nm] - :param float dy1, dy2: distance between grid and the one end of magnet - in y direction [nm] - :param float dz1, dz2: distance between grid and the one end of magnet - in z direction [nm] + Optimized by numba. See Bzxx_method for the explanation. + + :param float dx1: distance between grid and one end of magnet in + :math:`x` direction [nm] + :param float dx2: distance between grid and other end of magnet in + :math:`x` direction [nm] + :param float dy1: distance between grid and one end of magnet in + :math:`y` direction [nm] + :param float dy2: distance between grid and other end of magnet in + :math:`y` direction [nm] + :param float dz1: distance between grid and one end of magnet in + :math:`z` direction [nm] + :param float dz2: distance between grid and other end of magnet in + :math:`z` direction [nm] """ return ( diff --git a/mrfmsim/component/sample.py b/mrfmsim/component/sample.py index 7063158..056695c 100644 --- a/mrfmsim/component/sample.py +++ b/mrfmsim/component/sample.py @@ -28,9 +28,9 @@ class Sample(ComponentBase): :param float temperature: the sample temperature [K] :param float spin_density: the sample spin density :math:`\rho` [1/nm^3] :param float Gamma: spin gyromagnetic ratio [rad/s.mT] - defaults to None if spin_type is one of the preset - :param float L: spin angular momentum [unitless] - default to None if spin_type is one of the preset + defaults to None if spin is one of the preset types + :param float J: spin angular momentum [unitless] + defaults to None if spin is one of the preset types :param float dB_hom: homogeneous linewidth [mT] :param float dB_sat: saturation linewidth [mT] """ diff --git a/mrfmsim/formula/field.py b/mrfmsim/formula/field.py index 5f8a966..ed38d65 100644 --- a/mrfmsim/formula/field.py +++ b/mrfmsim/formula/field.py @@ -1,4 +1,4 @@ -"""Cacluations related to the magnetic field.""" +"""Calculations related to the magnetic field.""" import numpy as np import numba as nb diff --git a/mrfmsim/formula/magnetization.py b/mrfmsim/formula/magnetization.py index 63b1b88..9062f00 100644 --- a/mrfmsim/formula/magnetization.py +++ b/mrfmsim/formula/magnetization.py @@ -9,13 +9,10 @@ def mz_eq(B_tot, Gamma, J, temperature): r"""Magnetization per spin at the thermal equilibrium using the Brillouin function. - :param float gamma: the gyromagnetic ratio. [rad/s.mT] - :param float j: total spin angular momentum + :param float B_tot: total magnetic field [mT] + :param float Gamma: the gyromagnetic ratio [rad/s.mT] + :param float J: total spin angular momentum :param float temperature: the spin temperature [K] - :param float spin_density: the sample spin - density :math:`\rho` [1/nm^3] - :param float b0: the external magnetic field [mT] - :param float bz: tip magnetic field in z [mT] :return: equilibrium per-spin magnetization [aN.nm/mT] The outputs are calculated from the sample properties @@ -82,9 +79,10 @@ def mz_eq(B_tot, Gamma, J, temperature): def mz2_eq(Gamma, J): r"""Compute the magnetization variance per spin. - :param float gamma: the gyromagnetic ratio. [rad/s.mT] + :param float Gamma: the gyromagnetic ratio [rad/s.mT] :param float J: total spin angular momentum - :return: Mz2_eq, rhoMz_eq + :return: magnetization variance per spin [aN^2.nm^2/mT^2] + :rtype: float """ mu = HBAR * Gamma * np.sqrt(J * (J + 1) / 3.0) # aN.nm/mT diff --git a/mrfmsim/formula/misc.py b/mrfmsim/formula/misc.py index 48b4a36..81d704f 100644 --- a/mrfmsim/formula/misc.py +++ b/mrfmsim/formula/misc.py @@ -9,7 +9,10 @@ def convert_grid_pts(distance, grid_step): """Convert distance to ext points. - :param int distance: distance in the x direction. + :param float distance: distance in the :math:`x` direction [nm] + :param list[float] grid_step: grid step size [nm] + :return: number of grid points + :rtype: int """ return math.floor(distance / grid_step[0]) @@ -76,16 +79,18 @@ def singlespin_analytical( \frac{4\hat{y}^3}{3\pi(1+\hat{y}^2)^2}[(1+\hat{y}^2)E(-1/\hat{y}^2) - (\hat{y}^2 -1)K(-1/\hat{y}^2) - :param float Gamma: the gyromagnetic ratio + :param float Gamma: the gyromagnetic ratio [rad/s.mT] + :param str geometry: experiment geometry ('spam' or 'hangdown') :param float J: the spin angular momentum - :param array magnet_origin: the origin of the magnet - :param float magnet_radius: the radius of the magnet - :param float mu0_Ms: the saturation magnetization of the magnet - :param float mu_z: the spin magnetic moment - :param float magnet_spin_distance: magnet-spin distance + :param float magnet_spin_dist: magnet-spin distance [nm] + :param list magnet_origin: the origin of the magnet [nm] + :param float magnet_radius: the radius of the magnet [nm] + :param float mu0_Ms: the saturation magnetization of the magnet [mT] + :param float x_0p: zero-to-peak amplitude of the cantilever [nm] - :return: The analytical solution for a single spin (effective force). + :return: The analytical solution for a single spin (effective force) [aN]. The spin constant shift is the effective force divided by the 0 to peak amplitude. + :rtype: float """ mu_z = HBAR * Gamma * J From f35b214a1af2ec9b35f74f736f5ffc1f4c319d46 Mon Sep 17 00:00:00 2001 From: Peter Sun Date: Thu, 30 Oct 2025 19:43:36 -0400 Subject: [PATCH 39/45] Update feature_request.md --- .github/ISSUE_TEMPLATE/feature_request.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index eb02e42..70021af 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -12,8 +12,7 @@ assignees: '' ## Problem/Motivation - + ## Proposed Solution From 1b771db6301a46aba3da3a8247f5522126fb82d2 Mon Sep 17 00:00:00 2001 From: Peter Sun Date: Thu, 30 Oct 2025 19:58:23 -0400 Subject: [PATCH 40/45] Update templates --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- .github/pull_request_template.md | 51 +++++++++++----------------- 2 files changed, 20 insertions(+), 33 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 4395f95..77dbf68 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -31,7 +31,7 @@ assignees: '' -- **OS:** [e.g., macOS 13.0, Ubuntu 22.04, Windows 11] +- **OS:** [e.g., macOS 26.0, Ubuntu 22.04, Windows 11] - **Python Version:** [e.g., 3.9.7, 3.10.5] - **mrfmsim Version:** [e.g., 0.1.0, or commit hash if installed from source] - **Installation Method:** [e.g., pip, conda, from source] diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index cfb96b5..2aeaa48 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,3 +1,15 @@ +## Description + + + +## Changes Made + + + +- +- +- + ## Type of Pull Request @@ -11,10 +23,6 @@ - [ ] Test coverage improvement - [ ] Other (please describe): -## Description - - - ## Related Issue(s) @@ -22,21 +30,13 @@ -## Changes Made - - - -- -- -- - ## Breaking Changes -## Testing Performed +## Testing @@ -58,31 +58,18 @@ - [ ] Added usage examples (if applicable) - [ ] Documentation builds without errors (`cd docs && make html`) -## Code Quality +## Checklist - [ ] Code follows PEP 8 style guidelines (use ``Black`` formatter's default settings) - [ ] Used meaningful variable and function names - [ ] Code is modular and readable - -## Checklist - - - -- [ ] My code follows the project's coding standards -- [ ] I have performed a self-review of my own code -- [ ] I have commented my code, particularly in hard-to-understand areas -- [ ] My changes generate no new warnings or errors -- [ ] I have checked that this PR focuses on a single feature or bug fix +- [ ] Commented code, particularly in hard-to-understand areas +- [ ] Changes generate no new warnings or errors +- [ ] PR focuses on a single feature or bug fix ## Additional Notes - - - -## Screenshots (if applicable) - - - - + From 04b5ed757c2c8bff4d5d136cd42c601272b5c8b4 Mon Sep 17 00:00:00 2001 From: Peter Sun Date: Thu, 30 Oct 2025 22:33:27 -0400 Subject: [PATCH 41/45] Change mmodel version requirement --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index fa54b2d..3d7f4b0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,7 +22,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry.dependencies] python = ">=3.10" numpy = ">=1.26.4" -mmodel = { git = "https://www.github.com/Marohn-Group/mmodel.git", branch = "develop-0.8.1" } +mmodel = ">=0.9.0" numba = ">=0.60.0" scipy = ">=1.14.1" tox = { version = ">=3.25.0", optional = true } From 4fdcf29a68c7fc5f1563686ce155a9a1c0a06763 Mon Sep 17 00:00:00 2001 From: Peter Sun Date: Fri, 31 Oct 2025 11:07:12 -0400 Subject: [PATCH 42/45] Update CHANGELOG.rst --- CHANGELOG.rst | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 7a61f84..39e7e6f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -10,13 +10,21 @@ and this project adheres to [unreleased] ------------ -Minor fixes to documentation. +Added Cylinder Magnet and minor fixes to docstrings and documentation. Changed ^^^^^^^ - Change the CERMITD experiment graph to avoid output duplication. +- Change the API to use the latest version of the mmodel package (0.9.0). +- Modify the Nan treatment of ``polarization.rel_dpol_sat_td`` (#4) +- Reformat the docstrings and documentations +Added +^^^^^ + +- Add ``CylinderMagnetApprox`` class to approximate the magnetic field of a cylinder magnet (#4) +- Add pull request and issue templates. [0.3.0] - 2025-02-25 ---------------------- From 78666417e143a64e273852b0a6301e63476b3687 Mon Sep 17 00:00:00 2001 From: Peter Sun Date: Fri, 31 Oct 2025 11:27:00 -0400 Subject: [PATCH 43/45] Change to auto numbered footnote --- mrfmsim/component/cylindermagnet.py | 4 ++-- mrfmsim/component/magnet.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mrfmsim/component/cylindermagnet.py b/mrfmsim/component/cylindermagnet.py index c3076b6..ab10eb9 100644 --- a/mrfmsim/component/cylindermagnet.py +++ b/mrfmsim/component/cylindermagnet.py @@ -126,7 +126,7 @@ def Bz_method(self, x, y, z): these rectangular blocks are arranged side by side. The magnetic field of each rectangular magnet is calculated following the - method described in Ravaud2009 [1]_. The magnet is set up so that the + method described in Ravaud2009 [#]_. The magnet is set up so that the :math:`x` and :math:`y` dimensions are centered about the zero point. The translation in :math:`z` shifts the tip of the magnet in the :math:`z`-direction to be the given distance from the surface. @@ -152,7 +152,7 @@ def Bz_method(self, x, y, z): where :math:`\mu_0 M_s` is the magnet's saturation magnetization in mT. - .. [1] Ravaud, R. and Lemarquand, G. "Magnetic field produced by a + .. [#] Ravaud, R. and Lemarquand, G. "Magnetic field produced by a parallelepipedic magnet of various and uniform polarization" , *PIER*, **2009**, *98*, 207-219 [`10.2528/PIER09091704 `__]. diff --git a/mrfmsim/component/magnet.py b/mrfmsim/component/magnet.py index c0b403a..f227a96 100644 --- a/mrfmsim/component/magnet.py +++ b/mrfmsim/component/magnet.py @@ -213,7 +213,7 @@ def __post_init__(self): def Bz_method(self, x, y, z): r"""Calculate magnetic field :math:`B_z` [mT]. - The magnetic field is calculated following Ravaud2009 [1]_. + The magnetic field is calculated following Ravaud2009 [#]_. The magnet is set up so that the :math:`x` and :math:`y` dimensions are centered about the zero point. @@ -243,7 +243,7 @@ def Bz_method(self, x, y, z): where :math:`\mu_0 M_s` is the magnet's saturation magnetization in mT. - .. [1] Ravaud, R. and Lemarquand, G. "Magnetic field produced by a + .. [#] Ravaud, R. and Lemarquand, G. "Magnetic field produced by a parallelepipedic magnet of various and uniform polarization" , *PIER*, **2009**, *98*, 207-219 [`10.2528/PIER09091704 `__]. From 0c0c9de07a510528cd1fcde41ff668f51d61e60a Mon Sep 17 00:00:00 2001 From: Peter Sun Date: Fri, 31 Oct 2025 12:06:58 -0400 Subject: [PATCH 44/45] Update docstring and documentation --- mrfmsim/component/cylindermagnet.py | 3 ++- tests/test_component/test_cylindermagnet.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/mrfmsim/component/cylindermagnet.py b/mrfmsim/component/cylindermagnet.py index ab10eb9..caeeda8 100644 --- a/mrfmsim/component/cylindermagnet.py +++ b/mrfmsim/component/cylindermagnet.py @@ -10,7 +10,8 @@ class CylinderMagnetApprox(ComponentBase): :param float magnet_radius: cylinder magnet radius [nm] :param float magnet_length: cylinder magnet length [nm] - :param tuple magnet_origin: the position of the magnet origin (x, y, z) + :param tuple magnet_origin: the position of the magnet origin + :math:`(x, y, z)` [nm] :param float mu0_Ms: saturation magnetization [mT] """ diff --git a/tests/test_component/test_cylindermagnet.py b/tests/test_component/test_cylindermagnet.py index e03cb89..2874528 100644 --- a/tests/test_component/test_cylindermagnet.py +++ b/tests/test_component/test_cylindermagnet.py @@ -8,7 +8,7 @@ CylinderMagnetApprox -------------------- -All sphere magnets are tested using the parameters: +All cylinder magnets are tested using the parameters: radius = 0.5 nm length = 10 nm mu0_Ms = 1 mT From 8958768123e92194f4ca88116d3f187e3142214a Mon Sep 17 00:00:00 2001 From: Peter Sun Date: Fri, 31 Oct 2025 12:07:14 -0400 Subject: [PATCH 45/45] Add boundary nan value checks --- mrfmsim/formula/polarization.py | 16 +++++++++++++++- tests/test_formula/test_polarization.py | 22 ++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/mrfmsim/formula/polarization.py b/mrfmsim/formula/polarization.py index ae2b1b2..fe162fc 100644 --- a/mrfmsim/formula/polarization.py +++ b/mrfmsim/formula/polarization.py @@ -232,6 +232,10 @@ def rel_dpol_sat_td(Bzx, B1, ext_B_offset, ext_pts, Gamma, T2, tip_v): """Relative change in polarization for time-dependent saturation. The result is not a steady-state solution because it ignores T1 relaxation. + In the case where Bzx is 0, and B_offset is symmetric, the division will be nan. + Here we try to adjust the nan values to the average of the surrounding values. + However, if the resulting value is still nan or there are nan values at the boundary, + an ValueError is raised. """ # ignore division error the Exp takes care of the inf, and nan np.seterr(divide="ignore", invalid="ignore") @@ -245,7 +249,17 @@ def rel_dpol_sat_td(Bzx, B1, ext_B_offset, ext_pts, Gamma, T2, tip_v): # adjust the nan values to the average of the surrounding values for idx in np.where(np.isnan(div))[0]: - div[idx] = (div[idx + 1] + div[idx - 1]) / 2 + if idx == 0 or idx == len(div) - 1: + raise ValueError( + "Nan values at the boundary, check the Bzx and B_offset values." + ) + value = (div[idx + 1] + div[idx - 1]) / 2 + + if np.isnan(value): + raise ValueError( + "Nan value from division, check the Bzx and B_offset values." + ) + div[idx] = value rt = Gamma * B1**2 * np.abs(div) / tip_v dpol = np.exp(-rt) diff --git a/tests/test_formula/test_polarization.py b/tests/test_formula/test_polarization.py index d504238..7307a1b 100644 --- a/tests/test_formula/test_polarization.py +++ b/tests/test_formula/test_polarization.py @@ -197,6 +197,28 @@ def test_rel_dpol_sat_td_nan(sample_e): assert not np.any(np.isnan(rpol_b)) +def test_rel_dpol_sat_td_nan_boundary(sample_e): + """Test rel_dpol_sat_td raises an error if nan values are at the boundary.""" + Bzx = np.array([0, 0, -1]) + ext_B_offset = np.array([0, 0, 0, 0, 2]) + + with pytest.raises(ValueError, match="Nan values at the boundary"): + pol.rel_dpol_sat_td( + Bzx, 1.0, ext_B_offset, 1, sample_e.Gamma, sample_e.T2, 2000 + ) + + +def test_rel_dpol_sat_td_nan_division(sample_e): + """Test rel_dpol_sat_td raises an error if nan values are from division.""" + Bzx = np.array([2, 0, 0, -1]) + ext_B_offset = np.array([1, 0, 0, 0, 0, 1]) + + with pytest.raises(ValueError, match="Nan value from division"): + pol.rel_dpol_sat_td( + Bzx, 1.0, ext_B_offset, 1, sample_e.Gamma, sample_e.T2, 2000 + ) + + def test_rel_dpol_sat_td_without_td(sample_e): """Test rel_dpol_sat_td completely saturate spins if no td component.