Git Product home page Git Product logo

Comments (2)

shredEngineer avatar shredEngineer commented on May 18, 2024

Hey Steffen,

thanks for the kind words.

MagnetiCalc is very monolithic in that regard; putting all needed classes (SamplingVolume, Wire, BiotSavart, ...) together in a minimal example would take some work which I have not done yet.

All I can do right now is to give you MagnetiCalc v1.0 which is at least all in one file, but it also has some extra stuff in there, and it does NOT use any optimization, so it all runs on one core, without any speedups:

# (C) <mailto:[email protected]>
import numpy as np
import matplotlib.pyplot as plt

# Parametrisierung und Anzeige
animation = False       # Automatische 3D-Rotation
azim, elev = 270, 90    # Anfängliche 3D-Rotation
loops = 2               # Anzahl der Schleifen
radius = 2              # Radius der Gesamtschleife
height = 3              # Höhe einer Schleife
points = False          # Zeige nummerierte Schleifenpunkte
components = True       # Zeige die Komponenten der Parametrisierung der einzelnen Schleife
slicing = 16            # Elemente der Gesamtschleife in noch kleinere Segmente zerlegen
grid = True             # Koordinatensystem anzeigen

# Berechnung der magnetischen Flussdichte
I_DC = .25              # Stromstärke
B_box = 5               # "Radius" (halbe Seitenlänge) des zu berechnenden (kubischen) Volumens (zentriert um Nullpunkt)
B_res = 151             # Auflösung des Gitters
B_normalize = True      # Vektoren normalisieren
B_scale = .15           # Skalierung der Vektoren
B_alpha = 1.0           # Sichtbarkeit der Vektoren
B_limit = 100           # Vektoren mit größerem Betrag werden darauf begrenzt

torus = True            # Begrenze Feldberechnung auf einen Torus:
torus_shell_min = 1.5   # Radius der inneren Kugelschale
torus_shell_max = 2.5   # Radius der äußeren Kugelschale
torus_z_min = 0         # Untere Z-Ebene
torus_z_max = 0         # Obere Z-Ebene

# Parametrisierung der einzelnen Schleife
#              0  1  2  3  4  5  6  7  8  9 10 11
x = -np.array([0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3]) / 3 + 1/2
y = -np.array([0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0]) + 1/2
z = +np.array([0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0]) - 1/2
p = np.linspace(0, 1, len(x))

# Erzeuge die gewünschte Anzahl Schleifen mit vorgegebenem Radius (Gesamtschleife), schließe die Gesamtschleife
X, Y, Z = [], [], []
for a in np.linspace(0, 2 * np.pi, loops, endpoint=False):
    X = np.append(X, x * np.cos(a) - (y + radius) * np.sin(a))
    Y = np.append(Y, x * np.sin(a) + (y + radius) * np.cos(a))
    Z = np.append(Z, z * height)
X, Y, Z = np.append(X, X[0]), np.append(Y, Y[0]), np.append(Z, Z[0])
P = np.linspace(0, 1, len(X))

# Linienelemente der Gesamtschleife in noch kleinere Segmente zerlegen, schließe die Gesamtschleife
nX, nY, nZ = [], [], []
for i in range(len(P) - 1):
    p1 = np.array([X[i], Y[i], Z[i]])               # Startpunkt dieses Elements
    p2 = np.array([X[i + 1], Y[i + 1], Z[i + 1]])   # Endpunkt dieses Elements
    dI = p2 - p1                                    # Linienelement
    for j in range(slicing):
        nX = np.append(nX, X[i] + dI[0] * j / slicing)
        nY = np.append(nY, Y[i] + dI[1] * j / slicing)
        nZ = np.append(nZ, Z[i] + dI[2] * j / slicing)
X, Y, Z = np.append(nX, nX[0]), np.append(nY, nY[0]), np.append(nZ, nZ[0])
P = np.linspace(0, 1, len(X))

# Zeige Matplotlib-Fenster
fig = plt.figure(
    "MagnetiCalc-v1.0: Magnetic flux density calculation example <mailto:[email protected]>  ::  Drücke [q] zum Beenden",
    figsize=(12 if components else 6, 6)
)

if components:
    # Zeige die Komponenten der Parametrisierung der einzelnen Schleife
    ax_x = fig.add_subplot(322); ax_x.set(xlabel="$p$", ylabel="$x(p)$"); ax_x.plot(p, x); ax_x.scatter(p, x)
    ax_y = fig.add_subplot(324); ax_y.set(xlabel="$p$", ylabel="$y(p)$"); ax_y.plot(p, y); ax_y.scatter(p, y)
    ax_z = fig.add_subplot(326); ax_z.set(xlabel="$p$", ylabel="$z(p)$"); ax_z.plot(p, z); ax_z.scatter(p, z)

# Zeige die Gesamtschleife
ax_3d = fig.add_subplot(121 if components else 111, projection='3d', proj_type='ortho')
ax_3d.set(xlabel="$x$", ylabel="$y$", zlabel="$z$")
ax_3d.set_title(f"Radius = {radius}, Loops = {loops}", y=-0.086)
ax_3d.plot(X, Y, Z, c="r")

if not grid:
    # Verstecke das Koordinatensystem
    ax_3d.set_axis_off()

if points:
    # Zeige nummerierte Schleifenpunkte
    ax_3d.scatter(X, Y, Z)
    for i in range(len(P)):
        ax_3d.text(X[i], Y[i], Z[i], i)

# Berechne magnetische Flussdichte
side = np.linspace(-B_box, B_box, B_res)    # Koordinaten einer Gitterkante

# Erzeuge flaches Array der 3D-Gitterkoordinaten (Vektoren) und der Feldvektoren an jeder Gitterkoordinate
G, B = [], []
for gx in range(B_res):
    print(f"{100 * (gx + 1) / B_res:.2f} %")
    for gy in range(B_res):
        for gz in range(B_res):
            g = np.array([side[gx], side[gy], side[gz]])

            if torus:
                # Überspringe alle Punkte, die nicht auf Kreisscheiben in der XY-Ebene liegen
                g_dist = np.linalg.norm(np.array([side[gx], side[gy]]))
                if g_dist < torus_shell_min or g_dist > torus_shell_max:
                    continue

                # Überspringe alle Punkte, die nicht zwischen zwei Z-Ebenen liegen
                if g[2] < torus_z_min or g[2] > torus_z_max:
                    continue

            B_tot = np.zeros(3)  # Vektorieller Akkumulator

            # Iteriere über die Punkte der Gesamtschleife (allerletzter Punkt = allererster Punkt)
            for i in range(len(P) - 1):

                # Berechne Linienelement dI
                p1 = np.array([X[i], Y[i], Z[i]])               # Startpunkt dieses Elements
                p2 = np.array([X[i + 1], Y[i + 1], Z[i + 1]])   # Endpunkt dieses Elements
                dI = p2 - p1                                    # Linienelement
                m = p1 + dI / 2                                 # Mittelpunkt des Linienelements

                # Vektor und Abstand vom Mittelpunkt des Linienelements zur Gitterkoordinate
                R = g - m
                r = np.linalg.norm(R)

                # Berechne Flussdichteelement dB (Biot-Savart)
                dB = I_DC * np.cross(dI, R) / (r ** 3)

                # Vektorielle Superposition
                B_tot += dB

            # Betrag des gesamten Vektors
            B_mag = np.linalg.norm(B_tot)

            # Vektorlänge hart begrenzen
            if B_mag > B_limit:
                B_tot = B_tot / B_mag * B_limit

            # Speichere Koordinate und Feldvektor
            G.append(g)
            B.append(B_tot)

# Transponiere Gitter und Feld
Gx, Gy, Gz = [g[0] for g in G], [g[1] for g in G], [g[2] for g in G]
Bx, By, Bz = [b[0] for b in B], [b[1] for b in B], [b[2] for b in B]

# Zeige den Vektor der magnetischen Flussdichte an jeder Koordinate des 3D-Gitters
ax_3d.quiver(Gx, Gy, Gz, Bx, By, Bz, pivot="middle", length=B_scale, normalize=B_normalize, alpha=B_alpha)

# Erfrische Matplotlib-Fenster
plt.tight_layout()
figManager = plt.get_current_fig_manager()
figManager.window.showMaximized()

# Automatische 3D-Rotation
if animation:
    while plt.fignum_exists(fig.number):
        ax_3d.view_init(elev, azim)
        # azim += 1
        elev -= 1
        plt.draw()
        plt.pause(.001)
else:
    ax_3d.view_init(elev, azim)
    plt.show()

Let me know if this helps! :)

from magneticalc.

Steffen-W avatar Steffen-W commented on May 18, 2024

Hi @shredEngineer,

Thanks a lot the code looks really good. I will have a closer look and try it out the day after tomorrow. I would like to determine the inductance but in principle I can calculate the integral with the help of the field strength in space. That is facilitated with the code in any case. Thanks a lot

from magneticalc.

Related Issues (10)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.