Inductor_Model / app.py
TroglodyteDerivations's picture
Updated line 75 with: [removal] of ax[1].set_yscale('log')
116a9aa verified
import streamlit as st
import math
import matplotlib.pyplot as plt
import streamlit.components.v1 as components
class InductorModel:
def __init__(self, no_of_turns, cs_area, lengths, length_lg_2, mu_r, r, series_res):
self.no_of_turns = no_of_turns
self.cs_area = cs_area
self.lengths = lengths # Dictionary with keys 'a', 'b', 'c', 'w'
self.length_lg_2 = length_lg_2
self.mu_0 = 4 * math.pi * 1.0e-7
self.mu_r = mu_r
self.mu = self.mu_0 * mu_r
self.r = r
self.series_res = series_res
self.flux_linkage = 0
self.ind_current = 0
self.t1 = 0
self.dt = 1.0e-6
# Data for plotting
self.simulation_times = []
self.inductor_currents = []
self.voltage_sources = []
self.inductor_emfs = []
self.inductor_flux_linkages = []
def calculate_resistances(self):
R1 = (2 * self.lengths['a'] + self.lengths['b'] + 2.0 * self.lengths['w'] - 2 * self.length_lg_2) / (self.mu * self.cs_area)
Rg1 = 2 * self.length_lg_2 / (self.mu_0 * self.cs_area)
R2 = (self.lengths['b'] + self.lengths['w']) / (self.mu * self.cs_area)
R3 = (2 * self.lengths['c'] + self.lengths['b'] + 2.0 * self.lengths['w'] - 2 * self.length_lg_2) / (self.mu * self.cs_area)
Rg2 = self.length_lg_2 / (self.mu_0 * self.cs_area)
R_eq = R1 + Rg1 + (R2 * (R3 + Rg2) / (R2 + R3 + Rg2))
return R_eq
def update(self, vmeas, t_clock):
if t_clock >= self.t1:
R_eq = self.calculate_resistances()
k1 = (vmeas - self.ind_current * self.r)
k2 = (vmeas - (self.ind_current + self.dt * k1 / 2.0) * self.r)
k3 = (vmeas - (self.ind_current + self.dt * k2 / 2.0) * self.r)
k4 = (vmeas - (self.ind_current + self.dt * k3) * self.r)
k = (k1 + 2 * k2 + 2 * k3 + k4) * self.dt / 6.0
self.flux_linkage += k
flux = self.flux_linkage / self.no_of_turns
self.ind_current = flux * R_eq / self.no_of_turns
vsrc = vmeas - self.ind_current * self.series_res
indmodel_emf = vmeas - self.ind_current * self.r
# Store data for plotting
self.simulation_times.append(t_clock)
self.inductor_currents.append(self.ind_current)
self.voltage_sources.append(vsrc)
self.inductor_emfs.append(indmodel_emf)
self.inductor_flux_linkages.append(self.flux_linkage)
self.t1 += self.dt
def plot_results(self):
fig, ax = plt.subplots(2, 1, figsize=(12, 8))
ax[0].plot(self.simulation_times, self.inductor_flux_linkages, label='Flux Linkage')
ax[0].set_title('Core Flux Linkage Over Time')
ax[0].set_xlabel('Time')
ax[0].set_ylabel('Flux Linkage')
ax[0].set_yscale('log')
ax[0].legend()
ax[1].plot(self.simulation_times, self.inductor_emfs, label='Induced EMF', color='red')
ax[1].set_title('Induced EMF Over Time')
ax[1].set_xlabel('Time')
ax[1].set_ylabel('EMF')
ax[1].set_xscale('log')
ax[1].legend()
plt.tight_layout()
st.pyplot(fig)
@staticmethod # Defining as a static method. Consequently, the argument 'self' is not included in the constructor.
# Calling the method embed_youtube_video directly on the Circuit class or on an instance of the class.
def embed_youtube_video(url):
# Extract the video ID from the URL
video_id = url.split("=")[-1]
# Create the embed URL
embed_url = f"https://www.youtube.com/embed/{video_id}"
# Embed the video using an iframe
components.iframe(embed_url, width=700, height=400)
# Streamlit app
st.title('Inductor Simulation App')
no_of_turns = st.slider('Number of Turns', 100, 500, 200)
cs_area = st.slider('Cross-Sectional Area',9.0e-4) # step=1.0e-5
length_a = st.slider('Length A', 1.0e-2, 1.0e-1, 5.0e-2)
length_b = st.slider('Length B', 1.0e-2, 1.0e-1, 4.5e-2)
length_c = st.slider('Length C', 1.0e-2, 1.0e-1, 4.0e-2)
length_w = st.slider('Length W', 1.0e-2, 1.0e-1, 3.0e-2)
length_lg_2 = st.slider('Length LG2', 0.1e-3)
mu_r = st.slider('Relative Permeability', 100, 5000, 1000)
r = st.slider('Winding Resistance', 0.001, 0.1, 0.01)
series_res = st.slider('Series Resistance', 0.01, 1.0, 0.1)
vmeas = st.slider('Measured Voltage', 1, 20, 10)
inductor = InductorModel(no_of_turns, cs_area, {'a': length_a, 'b': length_b, 'c': length_c, 'w': length_w}, length_lg_2, mu_r, r, series_res)
if st.button('Run Simulation'):
t_clock = 0
while t_clock < 0.01:
inductor.update(vmeas, t_clock)
t_clock += inductor.dt
inductor.plot_results()
inductor.embed_youtube_video('https://www.youtube.com/watch?v=bSxCbdbSbbs')