Skip to content

Commit d9b39dc

Browse files
Adding rotations (#2)
* add magnet rotation * current rotation * prepare for 0.1.8 * add pre-commit config * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 03c95f8 commit d9b39dc

9 files changed

+110
-14
lines changed

.pre-commit-config.yaml

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
repos:
2+
- repo: https://github.com/pre-commit/pre-commit-hooks
3+
rev: v4.5.0
4+
hooks:
5+
- id: check-yaml
6+
- id: end-of-file-fixer
7+
types: [file, python]
8+
- id: trailing-whitespace
9+
types: [file, python]
10+
- id: check-added-large-files
11+
- id: debug-statements
12+
language_version: python3

CHANGELOG.md

+18
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
# v0.1.8
2+
- include Sphere magnets
3+
- rework of getFT workflow
4+
- include object rotations
5+
- update Readme
6+
7+
# v0.1.7
8+
- generalize to getFT instead of separate functions
9+
- add excessive FEM testing
10+
- physics tests
11+
- self-consitency tests
12+
13+
# v0.1.6
14+
- solve pypi problems
15+
16+
# v0.1.5
17+
- solve pypi problems
18+
119
# v0.1.4
220
- prepare for pypi
321
- rename into "magpylib-force"

magpylib_force/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"""
66

77
# module level dunders
8-
__version__ = "0.1.7"
8+
__version__ = "0.1.8"
99
__author__ = "SAL"
1010
__all__ = [
1111
"getFT",

magpylib_force/force.py

+17-7
Original file line numberDiff line numberDiff line change
@@ -117,12 +117,12 @@ def getFTmagnet(sources, targets, eps=1e-5, anchor=None):
117117
targets: Cuboid object or 1D list of Cuboid objects
118118
Force and Torque acting on targets in the magnetic field generated by the sources
119119
will be computed. A target must have a valid `meshing` parameter.
120-
120+
121121
eps: float, default=1e-5
122122
The magnetic field gradient is computed using finite differences (FD). eps is
123123
the FD step size. A good value is 1e-5 * characteristic system size (magnet size,
124124
distance between sources and targets, ...).
125-
125+
126126
anchor: array_like, default=None
127127
The Force adds to the Torque via the anchor point. For a freely floating magnet
128128
this would be the barycenter. If `anchor=None`, this part of the Torque computation
@@ -151,10 +151,20 @@ def getFTmagnet(sources, targets, eps=1e-5, anchor=None):
151151

152152
for i,tgt in enumerate(targets):
153153
tgt_vol = volume(tgt)
154-
inst_mom = tgt.magnetization * tgt_vol / inst_numbers[i]
154+
inst_mom = tgt.orientation.apply(tgt.magnetization) * tgt_vol / inst_numbers[i]
155155
MOM[insti[i]:insti[i+1]] = inst_mom
156156

157157
mesh = mesh_target(tgt)
158+
#import matplotlib.pyplot as plt
159+
#ax = plt.figure().add_subplot(projection='3d')
160+
#ax.plot(mesh[:,0], mesh[:,1], mesh[:,2], ls='', marker='.')
161+
162+
mesh = tgt.orientation.apply(mesh)
163+
#ax.plot(mesh[:,0], mesh[:,1], mesh[:,2], ls='', marker='.', color='r')
164+
#plt.show()
165+
#import sys
166+
#sys.exit()
167+
158168
for j,ev in enumerate(eps_vec):
159169
POSS[insti[i]:insti[i+1],j] = mesh + ev + tgt.position
160170

@@ -188,12 +198,12 @@ def getFTmagnet(sources, targets, eps=1e-5, anchor=None):
188198
# targets: Cuboid object or 1D list of Cuboid objects
189199
# Force and Torque acting on targets in the magnetic field generated by the sources
190200
# will be computed. A target must have a valid `meshing` parameter.
191-
201+
192202
# eps: float, default=1e-5
193203
# The magnetic field gradient is computed using finite differences (FD). eps is
194204
# the FD step size. A good value is 1e-5 * characteristic system size (magnet size,
195205
# distance between sources and targets, ...).
196-
206+
197207
# anchor: array_like, default=None
198208
# The Force adds to the Torque via the anchor point. For a freely floating magnet
199209
# this would be the barycenter. If `anchor=None`, this part of the Torque computation
@@ -292,14 +302,14 @@ def getFTcurrent(sources, targets, anchor=None, eps=None):
292302
CURR = np.zeros((no_inst,))
293303

294304
for i,tgt in enumerate(targets):
295-
verts = tgt.vertices
305+
verts = tgt.orientation.apply(tgt.vertices)
296306
mesh = mesh_numbers[i]
297307

298308
lvec = np.repeat(verts[1:] - verts[:-1], mesh, axis=0)/mesh
299309
LVEC[insti[i]:insti[i+1]] = lvec
300310

301311
CURR[insti[i]:insti[i+1]] = [tgt.current]*mesh*seg_numbers[i]
302-
312+
303313
for j in range(seg_numbers[i]):
304314
poss = np.linspace(verts[j]+lvec[j*mesh]/2, verts[j+1]-lvec[j*mesh]/2, mesh) + tgt.position
305315
POSS[insti[i]+mesh*j:insti[i]+mesh*(j+1)] = poss

magpylib_force/utility.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,4 @@ def check_input_targets(targets):
5151
# targets = [targets]
5252
# if not isinstance(targets, list):
5353
# raise ValueError("Bad targets input.")
54-
# return targets
54+
# return targets

tests/test_FEM.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ def test_ANSYS_magnet_current_close():
222222

223223
t1 = np.array((t[4], t[5], t[6]))*1e-9
224224
t2 = np.array((t[7], t[8], t[9]))*1e-9
225-
225+
226226
for wire in wires:
227227
wire.current = i0
228228
magnet.position = pos + np.array((0,0,.15))*1e-3

tests/test_basics.py

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import numpy as np
2+
import magpylib as magpy
3+
from magpylib_force import getFT
4+
5+
6+
def test_rotation1():
7+
"""
8+
test if rotated magnets give the correct result
9+
"""
10+
s1 = magpy.magnet.Sphere(diameter=1, polarization=(1,2,3))
11+
12+
c1 = magpy.magnet.Cuboid(
13+
dimension=(1,1,1),
14+
polarization=(0,0,1),
15+
position=(1,2,3),
16+
)
17+
c1.meshing = (5,5,5) # regular rectangular mesh in Cuboid
18+
19+
c2 = magpy.magnet.Cuboid(
20+
dimension=(1,1,1),
21+
polarization=(1,0,0),
22+
position=(1,2,3),
23+
)
24+
c2.meshing = (5,5,5) # regular rectangular mesh in Cuboid
25+
c2.rotate_from_angax(-90, 'y')
26+
27+
FT = getFT(s1, [c1, c2], anchor=(0,0,0))
28+
29+
np.testing.assert_allclose(FT[0], FT[1])
30+
31+
32+
def test_rotation2():
33+
"""
34+
test if rotated currents give the same result
35+
"""
36+
s1 = magpy.magnet.Sphere(diameter=1, polarization=(1,2,3), position=(0,0,-1))
37+
38+
verts1 = [(0,0,0), (1,0,0), (1,1,0), (0,1,0), (0,0,0)]
39+
verts2 = [(0,0,0), (1,0,0), (1,0,1), (0,0,1), (0,0,0)]
40+
41+
c1 = magpy.current.Polyline(
42+
vertices=verts1,
43+
current=1,
44+
)
45+
c1.meshing = 15
46+
47+
c2 = magpy.current.Polyline(
48+
vertices=verts2,
49+
current=1,
50+
)
51+
c2.meshing = 15
52+
c2.rotate_from_angax(-90, "x")
53+
54+
FT = getFT(s1, [c1, c2], anchor=(0,0,0))
55+
56+
np.testing.assert_allclose(FT[0], FT[1])

tests/test_interface.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ def test_getFT_target_inputs_01():
2222
FT1 = getFT(src1, wire1, anchor=(0,0,0))
2323
FT2 = getFT(src1, [wire1], anchor=(0,0,0))
2424
FT3 = getFT(src1, [wire1,wire2,wire3], anchor=(0,0,0))
25-
25+
2626
np.testing.assert_allclose(FT1,FT2)
2727
np.testing.assert_allclose(FT1,FT3[0])
2828
np.testing.assert_allclose(FT1,FT3[1])
2929
np.testing.assert_allclose(FT1,FT3[2])
3030

3131
FT4 = getFT(src1, wire1, anchor=(0,0,0))
3232
FT5 = getFT([src1, src2], wire1, anchor=(0,0,0))
33-
33+
34+
np.testing.assert_allclose(FT4*2,FT5)
3435
np.testing.assert_allclose(FT4*2,FT5)
35-
np.testing.assert_allclose(FT4*2,FT5)

tests/test_physics.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -261,4 +261,4 @@ def test_sphere_cube_at_distance():
261261
errT = (FT[0,1]-FT[1,1])/np.linalg.norm(FT[0,1])
262262

263263
assert max(abs(errF)) < 1e-5
264-
assert max(abs(errT)) < 1e-5
264+
assert max(abs(errT)) < 1e-5

0 commit comments

Comments
 (0)