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

Skip to content

Commit e68e9a0

Browse files
committed
Improves array api support for sphere core function
2 parents 41df331 + de2950c commit e68e9a0

File tree

3 files changed

+52
-25
lines changed

3 files changed

+52
-25
lines changed

pyproject.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ dependencies = [
3939
"plotly>=5.16",
4040
"array-api-compat>=1.11.2",
4141
"array-api-extra>=0.7.1",
42+
"typing-extensions>=4.13.2",
4243
]
4344

4445
[dependency-groups]
@@ -71,6 +72,9 @@ test = [
7172
"jupyterlab",
7273
"anywidget",
7374
"array-api-strict>=2.3.1",
75+
"jax",
76+
"numpy",
77+
"dask[array]",
7478
]
7579
binder = [
7680
"jupytext",

src/magpylib/_src/fields/field_BH_sphere.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
from array_api_compat import array_namespace
1111
from scipy.constants import mu_0 as MU0
1212

13-
from magpylib._src.input_checks import check_field_input
1413
from magpylib._src.array_api_utils import xp_promote
14+
from magpylib._src.input_checks import check_field_input
1515

1616

1717
# CORE
@@ -62,7 +62,9 @@ def magnet_sphere_Bfield(
6262
in the inside (see e.g. "Theoretical Physics, Bertelmann").
6363
"""
6464
xp = array_namespace(observers, diameters, polarizations)
65-
observers, diameters, polarizations = xp_promote(observers, diameters, polarizations, force_floating=True, xp=xp)
65+
observers, diameters, polarizations = xp_promote(
66+
observers, diameters, polarizations, force_floating=True, xp=xp
67+
)
6668
r = xp.linalg.vector_norm(observers, axis=-1)
6769
r_sphere = xp.abs(diameters) / 2.0
6870

@@ -90,8 +92,9 @@ def B_out(polarization, observers, r_sphere, r):
9092
/ 3.0
9193
).T
9294

93-
B = B_out(polarization, observers, r_sphere[xp.newaxis, :], r[xp.newaxis, :])
94-
B = xpx.at(B)[mask_in].set(B_in(polarization[mask_in]))
95+
B_o = B_out(polarization, observers, r_sphere[xp.newaxis, :], r[xp.newaxis, :])
96+
B_i = B_in(polarization)
97+
B = xp.where(mask_in, B_i, B_o)
9598

9699
return B
97100

tests/test_core.py

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
# here all core functions should be tested properly - ideally against FEM
22
from __future__ import annotations
33

4-
import array_api_strict as xp
4+
import array_api_strict
5+
import dask.array
6+
import jax
57
import numpy as np
8+
import pytest
9+
from array_api_extra.testing import lazy_xp_function, patch_lazy_xp_functions
610

711
from magpylib.core import (
812
current_circle_Hfield,
@@ -16,30 +20,46 @@
1620
triangle_Bfield,
1721
)
1822

23+
lazy_xp_function(current_circle_Hfield)
24+
lazy_xp_function(current_polyline_Hfield)
25+
lazy_xp_function(dipole_Hfield)
26+
lazy_xp_function(magnet_cuboid_Bfield)
27+
lazy_xp_function(magnet_cylinder_axial_Bfield)
28+
lazy_xp_function(magnet_cylinder_diametral_Hfield)
29+
lazy_xp_function(magnet_cylinder_segment_Hfield)
30+
lazy_xp_function(magnet_sphere_Bfield)
31+
lazy_xp_function(triangle_Bfield)
1932

20-
def test_magnet_sphere_Bfield():
33+
34+
@pytest.fixture(params=[np, array_api_strict, jax.numpy, dask.array])
35+
def xp(request, monkeypatch):
36+
patch_lazy_xp_functions(request, monkeypatch, xp=request.param)
37+
return request.param
38+
39+
40+
def test_magnet_sphere_Bfield(xp):
2141
"magnet_sphere_Bfield test"
2242
B = magnet_sphere_Bfield(
2343
observers=xp.asarray([(0, 0, 0)]),
2444
diameters=xp.asarray([1]),
2545
polarizations=xp.asarray([(0, 0, 1)]),
2646
)
2747
Btest = xp.asarray([(0, 0, 2 / 3)])
28-
np.testing.assert_allclose(B, Btest)
48+
np.testing.assert_allclose(B, Btest, rtol=1e-4)
2949

3050

31-
def test_current_circle_Hfield():
51+
def test_current_circle_Hfield(xp):
3252
Htest = xp.asarray([[0.09098208, 0.09415448], [0.0, 0.0], [0.07677892, 0.22625335]])
3353
H = current_circle_Hfield(
3454
r0=xp.asarray([1, 2]),
3555
r=xp.asarray([1, 1]),
3656
z=xp.asarray([1, 2]),
3757
i0=xp.asarray([1, 3]),
3858
)
39-
np.testing.assert_allclose(H, Htest)
59+
np.testing.assert_allclose(H, Htest, rtol=1e-4)
4060

4161

42-
def test_current_polyline_Hfield():
62+
def test_current_polyline_Hfield(xp):
4363
Htest = xp.asarray([[0.0, -2.29720373, 2.29720373], [0.0, 0.59785204, -0.59785204]])
4464

4565
H = current_polyline_Hfield(
@@ -48,10 +68,10 @@ def test_current_polyline_Hfield():
4868
segments_end=xp.asarray([(1, 0, 0), (-1, 0, 0)]),
4969
currents=xp.asarray([100, 200]),
5070
)
51-
np.testing.assert_allclose(H, Htest)
71+
np.testing.assert_allclose(H, Htest, rtol=1e-4)
5272

5373

54-
def test_dipole_Hfield():
74+
def test_dipole_Hfield(xp):
5575
Htest = xp.asarray(
5676
[
5777
[2.89501155e-13, 1.53146915e03, 1.53146915e03],
@@ -62,35 +82,35 @@ def test_dipole_Hfield():
6282
observers=xp.asarray([(1, 1, 1), (2, 2, 2)]),
6383
moments=xp.asarray([(1e5, 0, 0), (0, 0, 1e5)]),
6484
)
65-
np.testing.assert_allclose(H, Htest)
85+
np.testing.assert_allclose(H, Htest, atol=1e-6)
6686

6787

68-
def test_magnet_cuboid_Bfield():
88+
def test_magnet_cuboid_Bfield(xp):
6989
Btest = xp.asarray(
7090
[
71-
[1.56103722e-02, 1.56103722e-02, -3.53394965e-17],
72-
[7.73243250e-03, 6.54431406e-03, 1.04789520e-02],
91+
[1.5610372220113404e-02, 1.5610372220113404e-02, -3.5339496460705743e-17],
92+
[7.7324325000007145e-03, 6.5443140645650129e-03, 1.0478952028501879e-02],
7393
]
7494
)
7595
B = magnet_cuboid_Bfield(
7696
observers=xp.asarray([(1, 1, 1), (2, 2, 2)]),
7797
dimensions=xp.asarray([(1, 1, 1), (1, 2, 3)]),
7898
polarizations=xp.asarray([(0, 0, 1), (0.5, 0.5, 0)]),
7999
)
80-
np.testing.assert_allclose(B, Btest)
100+
np.testing.assert_allclose(B, Btest, atol=1e-6)
81101

82102

83-
def test_magnet_cylinder_axial_Bfield():
103+
def test_magnet_cylinder_axial_Bfield(xp):
84104
Btest = xp.asarray([[0.05561469, 0.04117919], [0.0, 0.0], [0.06690167, 0.01805674]])
85105
B = magnet_cylinder_axial_Bfield(
86106
z0=xp.asarray([1, 2]),
87107
r=xp.asarray([1, 2]),
88108
z=xp.asarray([2, 3]),
89109
)
90-
np.testing.assert_allclose(B, Btest)
110+
np.testing.assert_allclose(B, Btest, rtol=1e-4)
91111

92112

93-
def test_magnet_cylinder_diametral_Hfield():
113+
def test_magnet_cylinder_diametral_Hfield(xp):
94114
Btest = xp.asarray(
95115
[
96116
[-0.020742122169014, 0.007307203574376],
@@ -104,10 +124,10 @@ def test_magnet_cylinder_diametral_Hfield():
104124
z=xp.asarray([2, 3]),
105125
phi=xp.asarray([0.1, np.pi / 4]),
106126
)
107-
np.testing.assert_allclose(B, Btest)
127+
np.testing.assert_allclose(B, Btest, rtol=1e-4)
108128

109129

110-
def test_magnet_cylinder_segment_Hfield():
130+
def test_magnet_cylinder_segment_Hfield(xp):
111131
Btest = xp.asarray(
112132
[
113133
[-1948.14367497, 32319.94437208, 17616.88571231],
@@ -119,10 +139,10 @@ def test_magnet_cylinder_segment_Hfield():
119139
dimensions=xp.asarray([(1, 2, 0.1, 0.2, -1, 1), (1, 2, 0.3, 0.9, 0, 1)]),
120140
magnetizations=xp.asarray([(1e7, 0.1, 0.2), (1e6, 1.1, 2.2)]),
121141
)
122-
np.testing.assert_allclose(B, Btest)
142+
np.testing.assert_allclose(B, Btest, rtol=1e-4)
123143

124144

125-
def test_triangle_Bfield():
145+
def test_triangle_Bfield(xp):
126146
Btest = xp.asarray(
127147
[[7.45158965, 4.61994866, 3.13614132], [2.21345618, 2.67710148, 2.21345618]]
128148
)
@@ -136,4 +156,4 @@ def test_triangle_Bfield():
136156
),
137157
polarizations=xp.asarray([(1.0, 1.0, 1.0), (1.0, 1.0, 0.0)]) * 1e3,
138158
)
139-
np.testing.assert_allclose(B, Btest)
159+
np.testing.assert_allclose(B, Btest, rtol=1e-4)

0 commit comments

Comments
 (0)