|
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 |
|
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 |
|
|
|
|
|
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 |
|
|
|
|
|
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 |
|
|
|
def embed_youtube_video(url): |
|
|
|
video_id = url.split("=")[-1] |
|
|
|
embed_url = f"https://www.youtube.com/embed/{video_id}" |
|
|
|
components.iframe(embed_url, width=700, height=400) |
|
|
|
|
|
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) |
|
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') |