Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bdb83ca

Browse files
committed
Adds array api support to cylinder segment BHMJ level
1 parent 68e2a77 commit bdb83ca

File tree

2 files changed

+57
-28
lines changed

2 files changed

+57
-28
lines changed

src/magpylib/_src/fields/field_BH_cylinder_segment.py

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2375,42 +2375,47 @@ def BHJM_cylinder_segment(
23752375
- translate cylinder segment field to BHJM
23762376
- special cases catching
23772377
"""
2378+
xp = array_namespace(observers, dimension, polarization)
23782379
check_field_input(field)
23792380

2380-
BHJM = polarization.astype(float)
2381+
observers = xp.astype(observers, xp.float64)
2382+
dimension = xp.astype(dimension, xp.float64)
2383+
polarization = xp.astype(polarization, xp.float64)
23812384

2382-
r1, r2, h, phi1, phi2 = dimension.T
2383-
r1 = abs(r1)
2384-
r2 = abs(r2)
2385-
h = abs(h)
2385+
BHJM = xp.astype(polarization, xp.float64)
2386+
2387+
# r1, r2, h, phi1, phi2 = dimension.T
2388+
r1 = xp.abs(dimension[:, 0])
2389+
r2 = xp.abs(dimension[:, 1])
2390+
h = xp.abs(dimension[:, 2])
23862391
z1, z2 = -h / 2, h / 2
23872392

23882393
# transform dim deg->rad
2389-
phi1 = phi1 / 180 * np.pi
2390-
phi2 = phi2 / 180 * np.pi
2391-
dim = np.array([r1, r2, phi1, phi2, z1, z2]).T
2394+
phi1 = dimension[:, 3] / 180 * xp.pi
2395+
phi2 = dimension[:, 4] / 180 * xp.pi
2396+
dim = xp.asarray([r1, r2, phi1, phi2, z1, z2]).T
23922397

23932398
# transform obs_pos to Cy CS --------------------------------------------
2394-
x, y, z = observers.T
2395-
r, phi = np.sqrt(x**2 + y**2), np.arctan2(y, x)
2396-
pos_obs_cy = np.concatenate(((r,), (phi,), (z,)), axis=0).T
2399+
x, y, z = (observers[:, i] for i in range(3))
2400+
r, phi = xp.sqrt(x**2 + y**2), xp.atan2(y, x)
2401+
pos_obs_cy = xp.concat((r[None, ...], phi[None, ...], z[None, ...]), axis=0).T
23972402

23982403
# determine when points lie inside and on surface of magnet -------------
23992404

24002405
# mask_inside = None
24012406
# if in_out == "auto":
24022407
# phip1 in [-2pi,0], phio2 in [0,2pi]
24032408
phio1 = phi
2404-
phio2 = phi - np.sign(phi) * 2 * np.pi
2409+
phio2 = phi - xp.sign(phi) * 2 * xp.pi
24052410

24062411
# phi=phi1, phi=phi2
24072412
mask_phi1 = close(phio1, phi1) | close(phio2, phi1)
24082413
mask_phi2 = close(phio1, phi2) | close(phio2, phi2)
24092414

24102415
# r, phi ,z lies in-between, avoid numerical fluctuations (e.g. due to rotations) by including 1e-14
24112416
mask_r_in = (r1 - 1e-14 < r) & (r < r2 + 1e-14)
2412-
mask_phi_in = (np.sign(phio1 - phi1) != np.sign(phio1 - phi2)) | (
2413-
np.sign(phio2 - phi1) != np.sign(phio2 - phi2)
2417+
mask_phi_in = (xp.sign(phio1 - phi1) != xp.sign(phio1 - phi2)) | (
2418+
xp.sign(phio2 - phi1) != xp.sign(phio2 - phi2)
24142419
)
24152420
mask_z_in = (z1 - 1e-14 < z) & (z < z2 + 1e-14)
24162421

@@ -2425,13 +2430,13 @@ def BHJM_cylinder_segment(
24252430
# inside
24262431
mask_inside = mask_r_in & mask_phi_in & mask_z_in
24272432
# else:
2428-
# mask_inside = np.full(len(observers), in_out == "inside")
2429-
# mask_not_on_surf = np.full(len(observers), True)
2433+
# mask_inside = xp.full((observers.shape[0]), in_out == "inside")
2434+
# mask_not_on_surf = xp.full((observers.shape[0]), True)
24302435
# WARNING @alex
24312436
# 1. inside and not_on_surface are not the same! Can't just put to true.
24322437

24332438
# return 0 when all points are on surface
2434-
if not np.any(mask_not_on_surf):
2439+
if not xp.any(mask_not_on_surf):
24352440
return BHJM * 0
24362441

24372442
if field == "J":
@@ -2451,19 +2456,21 @@ def BHJM_cylinder_segment(
24512456
phi = phi[mask_not_on_surf]
24522457

24532458
# transform mag to spherical CS -----------------------------------------
2454-
m = np.sqrt(pol[:, 0] ** 2 + pol[:, 1] ** 2 + pol[:, 2] ** 2) / MU0 # J -> M
2455-
phi_m = np.arctan2(pol[:, 1], pol[:, 0])
2456-
th_m = np.arctan2(np.sqrt(pol[:, 0] ** 2 + pol[:, 1] ** 2), pol[:, 2])
2457-
mag_sph = np.concatenate(((m,), (phi_m,), (th_m,)), axis=0).T
2459+
m = xp.sqrt(pol[:, 0] ** 2 + pol[:, 1] ** 2 + pol[:, 2] ** 2) / MU0 # J -> M
2460+
phi_m = xp.atan2(pol[:, 1], pol[:, 0])
2461+
th_m = xp.atan2(xp.sqrt(pol[:, 0] ** 2 + pol[:, 1] ** 2), pol[:, 2])
2462+
mag_sph = xp.concat((m[None, ...], phi_m[None, ...], th_m[None, ...]), axis=0).T
24582463

24592464
# compute H and transform to cart CS -------------------------------------
24602465
H_cy = magnet_cylinder_segment_Hfield(
24612466
magnetizations=mag_sph, dimensions=dim, observers=pos_obs_cy
24622467
)
2463-
Hr, Hphi, Hz = H_cy.T
2464-
Hx = Hr * np.cos(phi) - Hphi * np.sin(phi)
2465-
Hy = Hr * np.sin(phi) + Hphi * np.cos(phi)
2466-
BHJM[mask_not_on_surf] = np.concatenate(((Hx,), (Hy,), (Hz,)), axis=0).T
2468+
Hr, Hphi, Hz = H_cy[:, 0], H_cy[:, 1], H_cy[:, 2]
2469+
Hx = Hr * xp.cos(phi) - Hphi * xp.sin(phi)
2470+
Hy = Hr * xp.sin(phi) + Hphi * xp.cos(phi)
2471+
BHJM[mask_not_on_surf] = xp.concat(
2472+
(Hx[None, ...], Hy[None, ...], Hz[None, ...]), axis=0
2473+
).T
24672474

24682475
if field == "H":
24692476
return BHJM
@@ -2484,3 +2491,25 @@ def BHJM_cylinder_segment(
24842491
# field_values=H_all,
24852492
# mask_inside=mask_inside & mask_not_on_surf,
24862493
# )
2494+
2495+
# return convert_HBMJ(
2496+
# output_field_type=field,
2497+
# polarization=polarization,
2498+
# input_field_type="H",
2499+
# field_values=H_all,
2500+
# mask_inside=mask_inside & mask_not_on_surf,
2501+
# )
2502+
2503+
# return convert_HBMJ(
2504+
# output_field_type=field,
2505+
# polarization=polarization,
2506+
# input_field_type="H",
2507+
# field_values=H_all,
2508+
# mask_inside=mask_inside & mask_not_on_surf,
2509+
# )
2510+
# output_field_type=field,
2511+
# polarization=polarization,
2512+
# input_field_type="H",
2513+
# field_values=H_all,
2514+
# mask_inside=mask_inside & mask_not_on_surf,
2515+
# )

tests/test_BHMJ_level.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,23 +214,23 @@ def test_BHJM_magnet_sphere():
214214

215215
def test_field_cylinder_segment_BH():
216216
"""CylinderSegment field test"""
217-
pol = np.array(
217+
pol = xp.asarray(
218218
[
219219
(0, 0, 0),
220220
(1, 2, 3),
221221
(2, 3, -1),
222222
(2, 3, -1),
223223
]
224224
)
225-
dim = np.array(
225+
dim = xp.asarray(
226226
[
227227
(1, 2, 3, 10, 20),
228228
(1, 2, 3, 10, 20),
229229
(1, 3, 2, -50, 50),
230230
(0.1, 5, 2, 20, 370),
231231
]
232232
)
233-
obs = np.array(
233+
obs = xp.asarray(
234234
[
235235
(1, 2, 3),
236236
(1, -1, 0),

0 commit comments

Comments
 (0)