Collections - Compounds
Contents
Collections - Compounds#
The Collection
class is a powerful tool for grouping and tracking object assemblies.
However, in many cases it is convenient to have assembly variables themselves (e.g. geometric arrangement) as class properties of new custom classes, which is achieved by sub-classing Collection
. We refer to such super-classes as compounds and show how to seamlessly integrate them into Magpylib.
Subclassing collections#
In the following example we design a compound class MagnetRing
which represents a ring of cuboid magnets with the parameter cubes
that should refer to the number of magnets on the ring. The ring will automatically adjust its size when cubes
is modified. In the spirit of Efficient 3D models we also add an encompassing 3D model.
import magpylib as magpy
class MagnetRing(magpy.Collection):
""" A ring of cuboid magnets
Parameters
----------
cubes: int, default=6
Number of cubes on ring.
"""
def __init__(self, cubes=6, **style_kwargs):
super().__init__(**style_kwargs) # hand over style args
self._update(cubes)
@property
def cubes(self):
""" Number of cubes"""
return self._cubes
@cubes.setter
def cubes(self, inp):
""" set cubes"""
self._update(inp)
def _update(self, cubes):
"""updates the MagnetRing instance"""
self._cubes = cubes
ring_radius = cubes/3
# construct in temporary Collection for path transfer
temp_coll = magpy.Collection()
for i in range(cubes):
child = magpy.magnet.Cuboid(
magnetization=(1000,0,0),
dimension=(1,1,1),
position=(ring_radius,0,0)
)
child.rotate_from_angax(360/cubes*i, 'z', anchor=0)
temp_coll.add(child)
# transfer path and children
temp_coll.position = self.position
temp_coll.orientation = self.orientation
self.children = temp_coll.children
# add parameter-dependent 3d trace
self.style.model3d.data = []
self.style.model3d.add_trace(self._custom_trace3d())
return self
def _custom_trace3d(self):
""" creates a parameter-dependent 3d model"""
r1 = self.cubes/3 - .6
r2 = self.cubes/3 + 0.6
trace = magpy.graphics.model3d.make_CylinderSegment(
dimension=(r1, r2, 1.1, 0, 360),
vert=150,
opacity=0.5,
)
return trace
The new MagnetRing
objects will seamlessly integrate into Magpylib and make use of the position and orientation interface, field computation and graphic display.
# add a sensor
sensor = magpy.Sensor(position=(0, 0, 0))
# create a MagnetRing object
ring = MagnetRing()
# move ring around
ring.position = (0,0,10)
ring.rotate_from_angax(angle=45, axis=(1,-1,0))
# compute field
print(f"B-field at sensor → {ring.getB(sensor).round(2)}")
# display graphically
magpy.show(ring, sensor, backend='plotly')
B-field at sensor → [0.1 0.1 0.08]