This is a major update that includes
- API changes
- New features
- Improved internal workings
Added
- New `orientation` property:
- The `orientation` attribute stores the relative rotation of an object with respect to the reference orientation (defined in each class docstring).
- The default (`orientation=None`) corresponds to a unit rotation.
- `orientation` is stored as a `scipy.spatial.transform.Rotation` object.
- Calling the attribute `source.orientation` returns a Scipy Rotation object `R`.
- Make use of all advantages of this great Scipy package:
- define `R.from_rotvec()` or `R.from_quat()` or ...
- view with `R.as_rotvec()` or `R.as_quat()` or ...
- combine subsequent rotations `R1 * R2 * R3`
- Sensor pixel:
- The new `Sensor(position, pixel, orientation)` class has the argument `pixel` which is `(0,0,0)` by default and refers to pixel positions inside the Sensor (in the Sensor local CS). `pixel` is an arbitrary array_like of the shape (N1, N2, ..., 3).
- Geometry paths:
- The `position` and `orientation` attributes can now store paths in the global CS. For a path of length M the attribute `position` is an array of the shape (M,3) and `orientation` is a Rotation object with length M. Each path position is associated with a respective rotation.
- Field computations `getB()` and `getH()` will evaluate the field for all source path positions.
- Paths can be set by hand `position = X`, `orientation = Y`, but they can also conveniently be generated using the `rotate` and `move` methods.
- Paths can be shown via the `show_path=True` kwarg in `display()`. By setting `show_path=x` the object will be displayed at every `x`'th path step. This helps to follow up on object rotation along the path.
- All objects have a `reset_path()` method defined to set their paths to `position=(0,0,0)` and `orientation=None`.
- Streamlining operation with all Magpylib objects:
- All objects (Sensors, Sources, Collections) have additional direct access to
- `.display()` method for quick self-inspection.
- `getB()` and `getH()` methods for fast field computations
- `__repr__` attribute defined and will return their type and their `id`.
- Other new features:
- The top-level `Config` allows users to access and edit Magpylib default values.
Changed
- Renamed modules:
- `.magnet` and `.current` sub-packages were moved to the top level.
- The `.moment` sub-package was renamed to `.misc` and was moved to the top level.
- The `.vector` sub-package was completely removed. Functionalities are mostly replaced by new top-level function `getBv()`.
- The `.math` sub-package was removed. Functionalities are mostly provided by the `scipy - Rotation` package.
- Renamed functions:
- The top level function `displaySystem()` was renamed to `display()`.
- Renamed attributes (parameters cannot be initialized in their short forms anymore):
- `angle` and `axis` are replaced by `orientation`
- `dimension` is replaced by `diameter` for Loop and Sphere classes.
- `angle`&`axis` are replaced by `orientation`.
- Modified rotate methods:
- The class methods `.rotate(angle, axis, anchor)` have been replaced by a new `.rotate(rotation, anchor, increment, start)` method where `rotation` ist a scipy `Rotation` object.
- The original angle-axis-anchor rotation is now provided by the new method `.rotate_from_angax(angle, axis, anchor, increment, start, degrees)`.
- The argument `axis` can now easily be set to the global CS axes with `"x"`, `"y"`, `"z"`.
- The anchor argument `anchor=0` represents the origin `(0,0,0)`.
- `angle` argument is in units of deg by default. It can now be set to rad using the `degrees` argument.
- The "move"-class method is now `.move(displacement, increment, start)`
- Rotation and move methods can now be used to generate paths using vector input and the `increment` and `start` arguments.
- All operations can now be chained (e.g. `.move_by().rotate().move_to()`)
- Miscellaneous:
- `getB(pos)` now takes single AND vector position arguments. If a vector is handed to getB it will automatically execute vectorized code from the vector module.
- In a finite region (size defined by `Config.EDGESIZE`) about magnet edges and line currents the field evaluates to `(0,0,0)` instead of `(NaN, NaN, NaN)`. Special case catching reduces performance slightly.
Updated
- Improved Computation:
- The Box field is now more stable. Numerical instabilities in the outfield were completely removed.
- Updated Field computation interface
- There are two fundamental arguments for field computation:
- The argument `sources` refers to a source/Collection or to a 1D list of L sources and/or Collections.
- The argument `observers` refers to a set of positions of shape (N1, N2, ..., 3) or a Sensor with `pixel` shape (N1, N2, ..., 3) or a 1D list of K Sensors.
- With Magpylib3 there are several ways to compute the field:
1. `source.getB(*observers)`
2. `sensor.getB(*sources)`
3. `magpylib.getB(sources, observers)`
- The output shape is always (L, M, K, N1, N2, ..., 3) with L sources, M path positions, K sensors and N (pixel) positions.
- Objects with shorter paths will be considered as static once their path ends while other paths continue.
4. `magpylib.getBv(**kwargs)` gives direct access to the field formulas and mostly replaces the `getBv_XXX()` functionality of v2. All inputs must be arrays of length N or of length 1 (statics will be tiled).
- While `getBv` is the fastest way to compute the fields it is much more convenient to use `getB()` which mostly provides the same performance. Specifically,the new `getB()` automatically groups all inputs for combined vectorized evaluation. This leads to a massive speedup when dealing with large Collections of similar sources.
- In addition to `getB`, the new `getH` returns the field in kA/m.
Removed
- the kwarg `niter=50` does not exist anymore for the Cylinder field computation. The functionality was completely replaced by the config setting `Config.ITER_CYLINDER=50`.
---