Package: rustpycoils
rustpycoilsPython wrapper aroundrustycoils.This module provides an implementation of an algorithm for finding the off-axis magnetic field of solenoidal systems of current loops.An analytic solution to the ideal wire loop is readily available and can be computed using elliptical integrals which are also readily available in libraries such as scipy. To approximate other solenoidal magnetic field systems, such as solenoids and Helmholtz coils, this basic primitive can be duplicated however this will start to slow down as more primitives are added. Additionally provided the magnetic field is only required to be accurately known close to the central axis of symmetry a faster power series method can be employed to determine the field for any system for which the on-axis magnetic field is known.This module impliments the primitive objects discussed inOff-axis expansion solution of Laplace's equation: Application to accurate and rapid calculation of coil magnetic fieldswhich crucially have analytic derivatives to arbitrary powers allowing for fast and accurate higher order derivatives of the total magnetic field to be computed. Using these primitives to build up the total system allows for magnetic systems of coils to be accurately and rapidly be computed close to the axis.InstallCan install using PyPipip install rustpycoilsIf pipy does not contain the binaries for your system wheels can be built usingmaturin, which requires a Rust compiler.git clone https://github.com/jdrtommey/rustpycoils/
cd rustpycoils
maturin build --releaseRange of ApplicitabilityThis is not a general alternative for modules such asmagpylibwhich offer analytic expressions for magnetic fields based on primitives, and provided there is no material response, give exact solutions. It is instead useful when a magnetic field with cylindrical symmetry is being calculated, which needs to be computed fast for a region close to the central axis. This can be highlighted by comparing the speed of the algorithm against the analytical provided inmagpylibfor the ideal wire loop. The test uses a wire loop with a radius of 1m and a current of 1A.Speed comparisionAs can be seen inset in the left-hand figure this library can compute the magnetic field of a single position around 200 times faster (performed on 4-core 1.4Ghz Intel i5 MacBook pro). The speed then continues to scale better, particularily after around 4000 positions. The speed increase is more dramatic when more  wire loops are included in the calculation, such as to model a solenoid or a pair of helmholtz coils. This is shown on the right where the magnetic field is computed at a single location at the center of the coils as the number of coils increases.Accuracy ComparisonHowever, caution needs to be taken to ensure this algorithm is used correctly. Unlike the solution provided by elliptical integrals, this algorthim is not accurate everywhere. The paper from which this library is derived claims accuracies of around 0.1% can be achieved at radial positions 70% of the radius.The agreement between the two libraries for both the axial (left) and radial (right) magnetic fields for positions which are located 70cm away from the middle of the wire loop. The agreement between the two codes saturates at around 1e-8% due to the discreprency in the definition of the vacuum permeability, where magpylib appears to be using 4π e-7 H/m, while this module uses 1.25663706212 e-6 H/m.The agreement for a wide range of axial and radial positions is shown below:Up to around 20% of the radius of the coil the agreement is at the level of agreement in the vacuum permiability. For radial positions approaching, and larger than, the radius the algorithm performs very poorly unless located very far away along the axial direction. These comparisons only show the accuracies for the given input parameters however they give a good idea of the range of applicability of this aproach.UsageThe module exposes a single classimportrustycoils#object containing primitives sharing a symmetry axismycoil=AxialSystem()which defines a symmetry axis. Currently this symmetry axis can only be defined along the three cartesian axes (defaults to x). Eventually this will be arbitrary.mycoil.transform_x()mycoil.transform_y()mycoil.transform_z()Individual primitive coils can be added to the AxialSystem with a unique string identifier. The units are SI with radius,thickness,length and position in metres and current in Amperes. Positions of primitives relative to the AxialSystem are given from one end for the primitives with length, i.e., a 5m long solenoid at position 2m extends from 2m to 7m.#define physical parametersradius=1.0thickness=0.1current=1.0length=5.0position=2.0//positionalongthesymmetryaxismycoil.add_loop("loop1",radius,position,current)mycoil.add_annular("foo",radius,thickness,position,current)mycoil.add_solenoid("bar",radius,length,position,length)mycoil.add_coil("coil1",radius,length,thickness,position,current)The parameters controlling these primitives can be be modified by using the functions#change radius of the current loopmycoil.modify_radius("loop1",6.0)"loop1"#change length of the solenoid "bar"mycoil.modify_length("bar",3.0)#change length of the coil "coil1"mycoil.modify_position("coil1",3.0)#change thickness of the annular "foo"mycoil.modify_thickness("foo",1.0)#change current of the annular "foo"mycoil.modify_current("foo",1.0)These functions accept keywords to modify multiple primitives at once. Note these keywords can not be used as identifiers for primitives.Reserved wordMeaning*Apply to allLOOPApply to current loopsANNULARApply to annularsSOLENOIDApply to solenoidsCOILApply to coils#changes all the current of all primitivesmycoil.modify_current("*",6.0)#changes all the current of all current loop primitivesmycoil.modify_current("LOOP",6.0)#changes all the radius of all annnlar primitivesmycoil.modify_radius("ANNULAR",6.0)#changes all the length of all solenoid primitivesmycoil.modify_length("SOLENOID",6.0)#changes all the length of all coil primitivesmycoil.modify_thickness("COIL",6.0)The magnetic field in each of the cartesian directions can be computed using an input of a numpy array. Currently requires a 2D numpy array
to work which is a little tedious for a single field value.fields=mycoil.get_field(np.asarray([x,y,z]).reshape(3,-1),1e-18)where 1e-18 is the tolerance to stop including additional terms in the power expansion.