11import numpy as np
22import magpylib as magpy
3- from magpylib_force .mesh import mesh_cuboid
3+ from magpylib_force .meshing import mesh_cuboid
44from magpylib_force .utility import check_input_anchor
5- from magpylib_force .utility import check_input_targets_Cuboid
6- from magpylib_force .utility import check_input_targets_Polyline
5+ from magpylib_force .utility import check_input_targets
6+ from magpylib ._src .obj_classes .class_current_Polyline import Polyline
7+ from magpylib ._src .obj_classes .class_magnet_Cuboid import Cuboid
8+
9+
10+ def getFT (sources , targets , anchor = None , eps = 1e-5 , squeeze = True ):
11+ """
12+ Compute force and torque between sources and targets.
13+ SI units are assumed for all inputs and outputs.
14+
15+ Parameters
16+ ----------
17+ sources: source and collection objects or 1D list thereof
18+ Sources that generate the magnetic field. Can be a single source (or collection)
19+ or a 1D list of l sources and/or collection objects.
20+
21+ targets: single object or 1D list of t objects that are in [Cuboid, Polyline]
22+ Force and Torque acting on targets in the magnetic field generated by the sources
23+ will be computed. A target must have a valid `meshing` parameter.
24+
25+ eps: float, default=1e-5
26+ For magnet-targets the magnetic field gradient is computed using finite
27+ differences (FD). `eps` is the FD step size. A good value
28+ is 1e-5 * characteristic system size (magnet size, distance between sources
29+ and targets, ...).
30+
31+ anchor: array_like, default=None
32+ The Force adds to the Torque via the anchor point. For a freely floating magnet
33+ this would be the barycenter. If `anchor=None`, this part of the Torque computation
34+ is ommitted.
35+
36+ squeeze: bool, default=True
37+ The output of the computation has the shape (n,3) where n corresponds to the number
38+ of targets. By default this is reduced to (3,) when there is only one target.
39+
40+ Returns
41+ -------
42+ Force-Torque as ndarray of shape (2,3), of (t,2,3) when t targets are given
43+ """
44+ anchor = check_input_anchor (anchor )
45+ targets = check_input_targets (targets )
46+ # MISSING: allow Collections
47+
48+ n = len (targets )
49+
50+ cuboids , order_cub = [], []
51+ polylines , order_poly = [], []
52+ for i ,t in enumerate (targets ):
53+ if isinstance (t , Cuboid ):
54+ cuboids .append (t )
55+ order_cub .append (i )
56+ elif isinstance (t , Polyline ):
57+ polylines .append (t )
58+ order_poly .append (i )
59+
60+ FT = np .zeros ((n , 2 , 3 ))
61+ if cuboids :
62+ FT_cube = getFTcube (sources , cuboids , eps = eps , anchor = anchor , squeeze = False )
63+ FT_cube = np .swapaxes (FT_cube , 0 , 1 )
64+ for ft ,o in zip (FT_cube , order_cub ):
65+ FT [o ] = ft
66+ if polylines :
67+ FT_poly = getFTwire (sources , polylines , anchor = anchor , squeeze = False )
68+ FT_poly = np .swapaxes (FT_poly , 0 , 1 )
69+ for ft ,o in zip (FT_poly , order_poly ):
70+ FT [o ] = ft
71+ #FT = np.swapaxes(FT, 0, 1)
72+ if squeeze :
73+ return np .squeeze (FT )
74+ return FT
775
876
977def getFTcube (sources , targets , eps = 1e-5 , anchor = None , squeeze = True ):
@@ -18,7 +86,7 @@ def getFTcube(sources, targets, eps=1e-5, anchor=None, squeeze=True):
1886
1987 targets: Cuboid object or 1D list of Cuboid objects
2088 Force and Torque acting on targets in the magnetic field generated by the sources
21- will be computed. A target must have a valid mesh parameter.
89+ will be computed. A target must have a valid `meshing` parameter.
2290
2391 eps: float, default=1e-5
2492 The magnetic field gradient is computed using finite differences (FD). eps is
@@ -34,15 +102,12 @@ def getFTcube(sources, targets, eps=1e-5, anchor=None, squeeze=True):
34102 The output of the computation has the shape (n,3) where n corresponds to the number
35103 of targets. By default this is reduced to (3,) when there is only one target.
36104 """
37- anchor = check_input_anchor (anchor )
38- targets = check_input_targets_Cuboid (targets )
39- # MISSING: allow Collections
40105
41106 # number of Cuboids
42107 tgt_number = len (targets )
43108
44109 # number of instances of each Cuboid
45- inst_numbers = np .array ([np .prod (tgt .mesh ) for tgt in targets ])
110+ inst_numbers = np .array ([np .prod (tgt .meshing ) for tgt in targets ])
46111
47112 # total number of instances
48113 no_inst = np .sum (inst_numbers )
@@ -85,7 +150,7 @@ def getFTcube(sources, targets, eps=1e-5, anchor=None, squeeze=True):
85150 F = np .squeeze (F )
86151 T = np .squeeze (T )
87152
88- return F , T
153+ return np . array (( F , T ))
89154
90155
91156
@@ -96,21 +161,17 @@ def getFTwire(sources, targets, anchor=None, squeeze=True):
96161 info:
97162 targets = Polyline objects
98163 segements = linear segments within Polyline objects
99- instances = computation instances, each segment is split into `mesh ` points
164+ instances = computation instances, each segment is split into `meshing ` points
100165 """
101166
102- anchor = check_input_anchor (anchor )
103- targets = check_input_targets_Polyline (targets )
104- # MISSING: allow Collections
105-
106167 # number of Polylines
107168 tgt_number = len (targets )
108169
109170 # segments of each Polyline
110171 seg_numbers = np .array ([len (tgt .vertices )- 1 for tgt in targets ])
111172
112173 # number of mesh-points of each Polyline
113- mesh_numbers = np .array ([tgt .mesh for tgt in targets ])
174+ mesh_numbers = np .array ([tgt .meshing for tgt in targets ])
114175
115176 # number of instances of each Polyline
116177 inst_numbers = seg_numbers * mesh_numbers
@@ -152,7 +213,7 @@ def getFTwire(sources, targets, anchor=None, squeeze=True):
152213 T = np .cross (anchor - POSS , F )
153214 T = np .array ([np .sum (T [insti [i ]:insti [i + 1 ]],axis = 0 ) for i in range (tgt_number )])
154215 else :
155- T = np .zeros ((tgt_number ,))
216+ T = np .zeros ((tgt_number ,3 ))
156217
157218 # sumup force for every target
158219 F = np .array ([np .sum (F [insti [i ]:insti [i + 1 ]],axis = 0 ) for i in range (tgt_number )])
@@ -162,4 +223,4 @@ def getFTwire(sources, targets, anchor=None, squeeze=True):
162223 F = np .squeeze (F )
163224 T = np .squeeze (T )
164225
165- return F , T
226+ return np . array (( F , T ))
0 commit comments