{"id":21140731,"url":"https://github.com/shredengineer/magneticalc","last_synced_at":"2025-07-27T07:30:34.380Z","repository":{"id":41190917,"uuid":"306765620","full_name":"shredEngineer/MagnetiCalc","owner":"shredEngineer","description":"MagnetiCalc calculates the magnetic field of arbitrary coils.","archived":false,"fork":false,"pushed_at":"2025-07-06T16:41:50.000Z","size":18193,"stargazers_count":50,"open_issues_count":0,"forks_count":4,"subscribers_count":2,"default_branch":"master-poetry","last_synced_at":"2025-07-06T17:25:25.625Z","etag":null,"topics":["coil","cuda","current","education","engineering","field-calculation","flux-density","gui","inductance","interactive","jit","linux","magnetic-field","magnetostatics","metric","python","simulation-modeling","vector-potential","visualization","wire"],"latest_commit_sha":null,"homepage":"https://paulwilhelm.de/magneticalc/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shredEngineer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-10-23T23:10:53.000Z","updated_at":"2025-07-06T16:41:23.000Z","dependencies_parsed_at":"2025-07-06T17:21:20.747Z","dependency_job_id":"a5b03ce5-7d6a-4cd8-8ce2-cc4a50ffdbf0","html_url":"https://github.com/shredEngineer/MagnetiCalc","commit_stats":null,"previous_names":[],"tags_count":45,"template":false,"template_full_name":null,"purl":"pkg:github/shredEngineer/MagnetiCalc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shredEngineer%2FMagnetiCalc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shredEngineer%2FMagnetiCalc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shredEngineer%2FMagnetiCalc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shredEngineer%2FMagnetiCalc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shredEngineer","download_url":"https://codeload.github.com/shredEngineer/MagnetiCalc/tar.gz/refs/heads/master-poetry","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shredEngineer%2FMagnetiCalc/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267324219,"owners_count":24069351,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-27T02:00:11.917Z","response_time":82,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["coil","cuda","current","education","engineering","field-calculation","flux-density","gui","inductance","interactive","jit","linux","magnetic-field","magnetostatics","metric","python","simulation-modeling","vector-potential","visualization","wire"],"created_at":"2024-11-20T07:17:33.458Z","updated_at":"2025-07-27T07:30:34.374Z","avatar_url":"https://github.com/shredEngineer.png","language":"Python","readme":"MagnetiCalc\n===========\n[![PyPI version](https://img.shields.io/pypi/v/MagnetiCalc?label=PyPI)](https://pypi.org/project/MagnetiCalc/)\n[![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](https://opensource.org/licenses/ISC)\n[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick\u0026hosted_button_id=TN6YTPVX36YHA\u0026source=url)\n[![Documentation](https://img.shields.io/badge/Documentation-API-orange)](https://shredengineer.github.io/MagnetiCalc/)\n\n🍀 [Always looking for beta testers!](#contribute)\n\n**What does MagnetiCalc do?**\n\nMagnetiCalc calculates the static magnetic flux density, vector potential, energy, self-inductance\nand magnetic dipole moment of arbitrary coils. Inside an OpenGL-accelerated GUI, the magnetic flux density\n($\\mathbf{B}$-field,\nin units of \u003ci\u003eTesla\u003c/i\u003e)\nor the magnetic vector potential\n($\\mathbf{A}$-field,\nin units of \u003ci\u003eTesla-meter\u003c/i\u003e)\nis displayed in interactive 3D, using multiple metrics for highlighting the field properties.\n\n\u003ci\u003eExperimental feature:\u003c/i\u003e To calculate the energy and self-inductance of permeable (i.e. ferrous) materials,\ndifferent core media can be modeled as regions of variable relative permeability;\nhowever, core saturation is currently not modeled, resulting in excessive flux density values.\n \n**Who needs MagnetiCalc?**\n\nMagnetiCalc does its job for hobbyists, students, engineers and researchers of magnetic phenomena.\nI designed MagnetiCalc from scratch, because I didn't want to mess around\nwith expensive and/or overly complex simulation software\nwhenever I needed to solve a magnetostatic problem.\n\n**How does it work?**\n\nThe $\\mathbf{B}$-field calculation\nis implemented using the Biot-Savart law [**1**], employing multiprocessing techniques;\nMagnetiCalc uses just-in-time compilation ([JIT](https://numba.pydata.org/))\nand, if available, GPU-acceleration ([CUDA](https://numba.pydata.org/numba-doc/dev/cuda/overview.html))\nto achieve high-performance calculations.\nAdditionally, the use of easily constrainable \"sampling volumes\" allows for selective calculation over\ngrids of arbitrary shape and arbitrary relative permeabilities\n$\\mu_r(\\mathbf{x})$\n(\u003ci\u003eexperimental\u003c/i\u003e).\n\nThe shape of any wire is modeled as a 3D piecewise linear curve.\nArbitrary loops of wire are sliced into differential current elements\n($\\mathbf{\\ell}$),\neach of which contributes to the total resulting field\n($\\mathbf{A}$,\n$\\mathbf{B}$)\nat some fixed 3D grid point ($\\mathbf{x}$),\nsumming over the positions of all current elements\n($\\mathbf{x^{'}}$):\n\n$\\mathbf{A}(\\mathbf{x})=I \\cdot \\frac{\\mu_0}{4 \\pi} \\cdot \\displaystyle \\sum_\\mathbf{x^{'}} \\mu_r(\\mathbf{x}) \\cdot \\frac{\\mathbf{\\ell}(\\mathbf{x^{'}})}{\\mid \\mathbf{x} - \\mathbf{x^{'}} \\mid}$\u003cbr\u003e\n\n$\\mathbf{B}(\\mathbf{x})=I \\cdot \\frac{\\mu_0}{4 \\pi} \\cdot \\displaystyle \\sum_\\mathbf{x^{'}} \\mu_r(\\mathbf{x}) \\cdot \\frac{\\mathbf{\\ell}(\\mathbf{x^{'}}) \\times (\\mathbf{x} - \\mathbf{x^{'}})}{\\mid \\mathbf{x} - \\mathbf{x^{'}} \\mid}$\u003cbr\u003e\n\nAt each grid point, the field magnitude (or field angle in some plane) is displayed\nusing colored arrows and/or dots;\nfield color and alpha transparency are individually mapped using one of the various\n[available metrics](#appendix-metrics).\n\nThe coil's energy $E$ [**2**]\nand self-inductance $L$ [**3**]\nare calculated by summing the squared\n$\\mathbf{B}$-field\nover the entire sampling volume;\nensure that the sampling volume encloses a large, non-singular portion of the field:\n\n$E=\\frac{1}{\\mu_0} \\cdot \\displaystyle \\sum_\\mathbf{x} \\frac{\\mathbf{B}(\\mathbf{x}) \\cdot \\mathbf{B}(\\mathbf{x})}{\\mu_r(\\mathbf{x})}$\u003cbr\u003e\n\n$L=\\frac{1}{I^{2}} \\cdot E$\u003cbr\u003e\n\nAdditionally, the scalar magnetic dipole moment\n$m$ [**4**]\nis calculated by summing over all current elements:\n\n$m=\\Bigl| I \\cdot \\frac{1}{2} \\cdot \\displaystyle \\sum_\\mathbf{x^{'}} \\mathbf{x^{'}} \\times \\mathbf{\\ell}(\\mathbf{x^{'}}) \\Bigr|$\u003cbr\u003e\n\n***References***\n\n[**1**]: Jackson, Klassische Elektrodynamik, 5. Auflage, S. 204, (5.4).\u003cbr\u003e\n[**2**]: Kraus, Electromagnetics, 4th Edition, p. 269, 6-9-1.\u003cbr\u003e\n[**3**]: Jackson, Klassische Elektrodynamik, 5. Auflage, S. 252, (5.157).\u003cbr\u003e\n[**4**]: Jackson, Klassische Elektrodynamik, 5. Auflage, S. 216, (5.54).\n\nScreenshot\n----------\n![Screenshot](https://raw.githubusercontent.com/shredEngineer/MagnetiCalc/master/dev/img/Screenshot.png)\n\n(Screenshot taken from the latest GitHub release.)\n\nExamples\n--------\n\nSome example projects can be found in the `examples/` folder.\n\nIf you feel like your project should also be included as an example, you are welcome to file an [issue](https://github.com/shredEngineer/MagnetiCalc/issues)!\n\nInstallation\n------------\n\nYou can install MagnetiCalc either as a standard user or as a developer.\n\n### For Users\n\nThis is the recommended way to install MagnetiCalc if you just want to use it.\n\n1.  **Install `pipx`**\n\n    `pipx` is a tool that allows you to install and run Python applications in isolated environments. If you don't have it already, you can install it with:\n\n    ```shell\n    sudo apt install pipx\n    ```\n\n2.  **Install MagnetiCalc**\n\n    ```shell\n    pipx install magneticalc\n    ```\n\n3.  **Run MagnetiCalc**\n\n    ```shell\n    magneticalc\n    ```\n\n### For Developers\n\nIf you want to contribute to MagnetiCalc, you'll need to set up a development environment.\n\n1.  **Install Poetry**\n\n    Poetry is a tool for dependency management and packaging in Python. You can find the installation instructions here: [https://python-poetry.org/docs/#installation](https://python-poetry.org/docs/#installation)\n\n2.  **Clone the repository**\n\n    ```shell\n    git clone https://github.com/shredEngineer/MagnetiCalc.git\n    cd MagnetiCalc\n    ```\n\n3.  **Install dependencies**\n\n    ```shell\n    poetry install\n    ```\n\n4.  **Run MagnetiCalc**\n\n    ```shell\n    poetry run magneticalc\n    ```\n\n### Enabling CUDA Support\nTested in Ubuntu 20.04, using the NVIDIA CUDA 10.1 driver and NVIDIA GeForce GTX 1650 GPU.\n\nPlease refer to the\n[Numba Installation Guide](https://numba.pydata.org/numba-doc/latest/user/installing.html)\nwhich includes the steps necessary to get CUDA up and running.\n\nLicense\n-------\nCopyright © 2020–2022, Paul Wilhelm, M. Sc. \u003c[anfrage@paulwilhelm.de](mailto:anfrage@paulwilhelm.de)\u003e\n\n\u003cb\u003eISC License\u003c/b\u003e\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted, provided that the above\ncopyright notice and this permission notice appear in all copies.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\nWITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\nANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\nWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\nACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\nOR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n\n[![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](https://opensource.org/licenses/ISC)\n\nContribute\n----------\n**You** are invited to contribute to MagnetiCalc!\n\nGeneral feedback, Issues and Pull Requests are always welcome.\n\nIf this software has been helpful to you in some way or another, please let me and others know!\n\n[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick\u0026hosted_button_id=TN6YTPVX36YHA\u0026source=url)\n\nDocumentation\n-------------\nThe documentation for MagnetiCalc is auto-generated from docstrings in the Python code.\n\n[![Documentation](https://img.shields.io/badge/Documentation-API-orange)](https://shredengineer.github.io/MagnetiCalc/)\n\n### Debugging\n\nIf desired, MagnetiCalc can be quite verbose about everything it is doing in the terminal:\n* Some modules are blacklisted in [`Debug.py`](magneticalc/Debug.py), but this can easily be changed.  \n* Some modules also provide their own debug switches to increase the level of detail. \n\nData Import/Export and Python API\n---------------------------------\n### GUI\nMagnetiCalc allows the following data to be imported/exported using the GUI:\n* Import/export wire points from/to TXT file.\n* Export $\\mathbf{A}$-/$\\mathbf{B}$-fields,\n  wire points and wire current to an [HDF5](https://www.h5py.org/) container for use in post-processing.\u003cbr\u003e\n  *Note:* You could use [Panoply](https://www.giss.nasa.gov/tools/panoply/download/) to open HDF5 files.\n  (The \"official\" [HDFView](https://www.hdfgroup.org/downloads/hdfview/) software didn't work for me.)\n\n### API\nThe [`API`](magneticalc/API.py) class\n([documentation](https://shredengineer.github.io/MagnetiCalc/magneticalc.API.API.html))\nprovides basic functions for importing/exporting data programmatically.\n\n#### Example: Wire Export\nGenerate a wire shape using [NumPy](https://numpy.org/) and export it to a TXT file:\n\n```python\nfrom magneticalc import API\nimport numpy as np\n\nwire = [\n    (np.cos(a), np.sin(a), np.sin(16 * a) / 5)\n    for a in np.linspace(0, 2 * np.pi, 200)\n]\n\nAPI.export_wire(\"Custom Wire.txt\", wire)\n```\n\n#### Example: Field Import\nImport an HDF5 file containing an\n$\\mathbf{A}$-field\nand plot it using [Matplotlib](https://matplotlib.org/stable/users/index.html):\n\n```python\nfrom magneticalc import API\nimport matplotlib.pyplot as plt\n\ndata = API.import_hdf5(\"examples/Custom Export.hdf5\")\naxes = data.get_axes()\na_field = data.get_a_field()\n\nax = plt.figure(figsize=(5, 5), dpi=150).add_subplot(projection=\"3d\")\nax.quiver(*axes, *a_field, length=1e5, normalize=False, linewidth=.5)\nplt.show()\n```\n\nThe imported data is wrapped in a [`MagnetiCalc_Data`](magneticalc/MagnetiCalc_Data.py) object\n([documentation](https://shredengineer.github.io/MagnetiCalc/magneticalc.MagnetiCalc_Data.MagnetiCalc_Data.html))\nwhich provides convenience functions for accessing, transforming and reshaping the data:\n\n| Method                                                   | Description                                                                                                                                                                                                                                                      |\n|----------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `.get_wire_list()`                                       | Returns a list of all 3D points of the wire.                                                                                                                                                                                                                     |\n| `.get_wire()`                                            | Returns the raveled wire points as three arrays.                                                                                                                                                                                                                 |\n| `.get_current()`                                         | Returns the wire current.                                                                                                                                                                                                                                        |\n| `.get_dimension()`                                       | Returns the sampling volume dimension as a 3-tuple.                                                                                                                                                                                                              |\n| `.get_axes_list()`                                       | Returns a list of all 3D points of the sampling volume.                                                                                                                                                                                                          |\n| `.get_axes()`                                            | Returns the raveled sampling volume coordinates as three arrays.                                                                                                                                                                                                 |\n| `.get_axes(reduce=True)`                                 | Returns the axis ticks of the sampling volume.                                                                                                                                                                                                                   |\n| `.get_a_field_list()`\u003cbr\u003e`.get_b_field_list()`           | Returns a list of all 3D vectors of the $\\mathbf{A}$- or $\\mathbf{B}$-field.                                     |\n| `.get_a_field()`\u003cbr\u003e`.get_b_field()`                     | Returns the raveled $\\mathbf{A}$- or $\\mathbf{B}$-field coordinates as three arrays.                             |\n| `.get_a_field(as_3d=True)`\u003cbr\u003e`.get_b_field(as_3d=True)` | Returns a 3D field for each component of the $\\mathbf{A}$- or $\\mathbf{B}$-field, indexed over the reduced axes. |\n\nToDo\n----\n**Functional**\n* Add a histogram for every metric.\n* Add an overlay for vector metrics, like gradient or curvature\n  (derived from the fundamental\n  $\\mathbf{A}$- and\n  $\\mathbf{B}$-fields).\n* Add a list of objects, for wires and permeability groups (constraints),\n  with a transformation pipeline for each object;\n  move the `Wire` widget to a dedicated dialog window instead.\n  (Add support for multiple wires, study mutual induction.)\n* Interactively display superposition of fields with varying currents.\n* Add (cross-)stress scalar metric: Ratio of absolute flux density contribution to actual flux density at every point.\n* Highlight permeability groups with\n  $\\mu_r \\neq 0$ in the 3D view.\n* Add support for multiple current values and animate the resulting fields.\n* Add support for modeling of core material saturation and hysteresis effects.\n* Provide a means to emulate permanent magnets.\n\n**Usability**\n* Move variations of each wire preset (e.g. the number of turns) into an individual sub-menu;\n  alternatively, provide a dialog for parametric generation.\n* Add stationary coordinate system and ruler in the bottom left corner.\n* Add support for selective display over a portion of the metric range,\n  enabling a kind of iso-contour display.\n* HDF5 container export from command line, without opening the GUI.\n\n**Known Bugs**\n* Fix issue where the points of a sampling volume with *fractional* resolution\n  are not always spaced equidistantly for some sampling volume dimensions.\n* Fix calculation of divergence right at the sampling volume boundary.\n* Fix missing scaling of VisPy markers when zooming.\n* Fix unnecessary shading of VisPy markers.\n\n**Performance**\n* Parallelize sampling volume calculation which is currently slow.\n\n**Code Quality**\n* Add unit tests.\n\nVideo\n-----\nA very short demo of MagnetiCalc in action:\n\n[![Magnetic Field Calculation with Python (MagnetiCalc)](https://raw.githubusercontent.com/shredEngineer/MagnetiCalc/master/dev/img/Video-Thumb.png)](https://www.youtube.com/watch?v=d3QKdYfOuvQ)\n\nLinks\n-----\nThere is also a short article about MagnetiCalc on my personal website:\n[paulwilhelm.de/magneticalc](https://paulwilhelm.de/magneticalc/)\n\n*Appendix:* Metrics\n-------------------\n\n| Metric               | Symbol                                       | Description                           |\n|----------------------|----------------------------------------------|---------------------------------------|\n| ``Magnitude``        | $\\mid\\vec{B}\\mid$                            | Magnitude in space                    |\n| ``Magnitude X``      | $\\mid\\vec{B}_{X}\\mid$                        | Magnitude in X-direction              |\n| ``Magnitude Y``      | $\\mid\\vec{B}_{Y}\\mid$                        | Magnitude in Y-direction              |\n| ``Magnitude Z``      | $\\mid\\vec{B}_{Z}\\mid$                        | Magnitude in Z-direction              |\n| ``Magnitude XY``     | $\\mid\\vec{B}_{XY}\\mid$                       | Magnitude in XY-plane                 |\n| ``Magnitude XZ``     | $\\mid\\vec{B}_{XZ}\\mid$                       | Magnitude in XZ-plane                 |\n| ``Magnitude YZ``     | $\\mid\\vec{B}_{YZ}\\mid$                       | Magnitude in YZ-plane                 |\n| ``Divergence``       | $\\nabla\\cdot\\vec{B}$                         | Divergence                            |\n| ``Divergence +``     | $+\\{\\nabla\\cdot\\vec{B}\\}_{\u003e0}$               | Positive Divergence                   |\n| ``Divergence –``     | $-\\{\\nabla\\cdot\\vec{B}\\}_{\u003c0}$               | Negative Divergence                   |\n| ``Log Magnitude``    | $\\log_{10} \\mid\\vec{B}\\mid$                  | Logarithmic Magnitude in space        |\n| ``Log Magnitude X``  | $\\log_{10} \\mid\\vec{B_X}\\mid$                | Logarithmic Magnitude in X-direction  |\n| ``Log Magnitude Y``  | $\\log_{10} \\mid\\vec{B_Y}\\mid$                | Logarithmic Magnitude in Y-direction  |\n| ``Log Magnitude Z``  | $\\log_{10} \\mid\\vec{B_Z}\\mid$                | Logarithmic Magnitude in Z-direction  |\n| ``Log Magnitude XY`` | $\\log_{10} \\mid\\vec{B}_{XY}\\mid$             | Logarithmic Magnitude in XY-plane     |\n| ``Log Magnitude XZ`` | $\\log_{10} \\mid\\vec{B}_{XZ}\\mid$             | Logarithmic Magnitude in XZ-plane     |\n| ``Log Magnitude YZ`` | $\\log_{10} \\mid\\vec{B}_{YZ}\\mid$             | Logarithmic Magnitude in YZ-plane     |\n| ``Log Divergence``   | $\\log_{10} \\ \\ \\nabla\\cdot\\vec{B}$           | Logarithmic Divergence                |\n| ``Log Divergence +`` | $\\log_{10} \\ +\\{\\nabla\\cdot\\vec{B}\\}_{\u003e0}$   | Positive Logarithmic Divergence       |\n| ``Log Divergence –`` | $\\log_{10} \\ -\\{\\nabla\\cdot\\vec{B}\\}_{\u003c0}$   | Negative Logarithmic Divergence       |\n| ``Angle XY``         | $\\measuredangle\\vec{B}_{XY}$                 | Field angle in XY-plane               |\n| ``Angle XZ``         | $\\measuredangle\\vec{B}_{XZ}$                 | Field angle in XZ-plane               |\n| ``Angle YZ``         | $\\measuredangle\\vec{B}_{YZ}$                 | Field angle in YZ-plane               |","funding_links":["https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick\u0026hosted_button_id=TN6YTPVX36YHA\u0026source=url"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshredengineer%2Fmagneticalc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshredengineer%2Fmagneticalc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshredengineer%2Fmagneticalc/lists"}