TroglodyteDerivations
commited on
Commit
•
7f5560f
1
Parent(s):
ebf0d85
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,204 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import numpy as np
|
3 |
+
import matplotlib.pyplot as plt
|
4 |
+
|
5 |
+
class MultiLimbCoreModel:
|
6 |
+
def __init__(self, no_of_turns, cs_area, lengths, length_lg_2, mu_r, r, series_res):
|
7 |
+
self.no_of_turns = no_of_turns
|
8 |
+
self.cs_area = cs_area
|
9 |
+
self.lengths = lengths # Dictionary keys 'a', 'b', 'c', 'w'
|
10 |
+
self.length_lg_2 = length_lg_2
|
11 |
+
self.mu_0 = 4 * np.pi * 1.0e-7
|
12 |
+
self.mu_r = mu_r
|
13 |
+
self.mu = self.mu_0 * self.mu_r
|
14 |
+
self.r = r
|
15 |
+
self.series_res = series_res
|
16 |
+
self.flux_linkage = 0
|
17 |
+
self.ind_current = 0
|
18 |
+
self.t1 = 0
|
19 |
+
self.dt = 1.0e-6
|
20 |
+
|
21 |
+
# Data for plotting
|
22 |
+
self.simulation_times = []
|
23 |
+
self.inductor_currents = []
|
24 |
+
self.voltage_sources = []
|
25 |
+
self.inductor_emfs = []
|
26 |
+
self.inductor_flux_linkages = []
|
27 |
+
self.indmodel_flux = []
|
28 |
+
self.indmodel_flux2 = []
|
29 |
+
self.indmodel_flux3 = []
|
30 |
+
self.phi_values = []
|
31 |
+
|
32 |
+
def calculate_resistances(self):
|
33 |
+
R1 = (2 * self.lengths['a'] + self.lengths['b'] + 2.0 * self.lengths['w'] - 2 * self.length_lg_2) / (self.mu * self.cs_area)
|
34 |
+
Rg1 = (2 * self.length_lg_2) / (self.mu_0 * self.cs_area)
|
35 |
+
R2 = (self.lengths['b'] + self.lengths['w']) / (self.mu * self.cs_area)
|
36 |
+
R3 = (2 * self.lengths['c'] + self.lengths['b'] + 2.0 * self.lengths['w'] - 2 * self.length_lg_2) / (self.mu * self.cs_area)
|
37 |
+
Rg2 = (self.length_lg_2) / (self.mu_0 * self.cs_area)
|
38 |
+
R_eq = R1 + Rg1 + (R2 * (R3 + Rg2) / (R2 + R3 + Rg2))
|
39 |
+
return R_eq, R1, Rg1, R2, Rg2, R3
|
40 |
+
|
41 |
+
def update(self, vmeas, t_clock):
|
42 |
+
if t_clock >= self.t1:
|
43 |
+
R_eq, R1, Rg1, R2, Rg2, R3 = self.calculate_resistances()
|
44 |
+
k1 = (vmeas - self.ind_current * self.r)
|
45 |
+
k2 = (vmeas - (self.ind_current + self.dt * k1 / 2.0) * self.r)
|
46 |
+
k3 = (vmeas - (self.ind_current + self.dt * k2 / 2.0) * self.r)
|
47 |
+
k4 = (vmeas - (self.ind_current + self.dt * k3) * self.r)
|
48 |
+
k = (k1 + 2 * k2 + 2 * k3 + k4) * self.dt / 6.0
|
49 |
+
self.flux_linkage += k
|
50 |
+
|
51 |
+
flux = self.flux_linkage / self.no_of_turns
|
52 |
+
self.ind_current = flux * R_eq / self.no_of_turns
|
53 |
+
phi = self.no_of_turns * self.ind_current / R_eq
|
54 |
+
vsrc = vmeas - self.ind_current * self.series_res
|
55 |
+
indmodel_emf = vmeas - self.ind_current * self.r
|
56 |
+
|
57 |
+
# Multi Core Limbs
|
58 |
+
indmodel_flux = flux
|
59 |
+
indmodel_flux2 = flux * (R2 * (R3 + Rg2) / (R2 + R3 + Rg2)) / R2
|
60 |
+
indmodel_flux3 = flux * (R2 * (R3 + Rg2) / (R2 + R3 + Rg2)) / R3
|
61 |
+
|
62 |
+
# Store data for plotting
|
63 |
+
self.simulation_times.append(t_clock)
|
64 |
+
self.inductor_currents.append(self.ind_current)
|
65 |
+
self.voltage_sources.append(vsrc)
|
66 |
+
self.inductor_emfs.append(indmodel_emf)
|
67 |
+
self.inductor_flux_linkages.append(self.flux_linkage)
|
68 |
+
self.indmodel_flux.append(indmodel_flux) # Limb 1
|
69 |
+
self.indmodel_flux2.append(indmodel_flux2) # Limb 2
|
70 |
+
self.indmodel_flux3.append(indmodel_flux3) # Limb 3
|
71 |
+
self.phi_values.append(phi)
|
72 |
+
|
73 |
+
self.t1 += self.dt
|
74 |
+
|
75 |
+
def plot_reluctances_of_each_limb(self):
|
76 |
+
fig, ax = plt.subplots(figsize=(12, 8))
|
77 |
+
ax.plot(self.simulation_times, self.indmodel_flux, label='Limb 1 Flux')
|
78 |
+
ax.plot(self.simulation_times, self.indmodel_flux2, label='Limb 2 Flux')
|
79 |
+
ax.plot(self.simulation_times, self.indmodel_flux3, label='Limb 3 Flux')
|
80 |
+
ax.set_xlabel('Time (s)')
|
81 |
+
ax.set_ylabel('Flux (Weber)')
|
82 |
+
ax.legend()
|
83 |
+
ax.set_title('Flux in Each Limb Over Time')
|
84 |
+
st.pyplot(fig)
|
85 |
+
|
86 |
+
def plot_reluctances_of_each_limb_log_base_10(self):
|
87 |
+
fig, ax = plt.subplots(figsize=(12, 8))
|
88 |
+
ax.plot(self.simulation_times, self.indmodel_flux, label='Limb 1 Flux')
|
89 |
+
ax.plot(self.simulation_times, self.indmodel_flux2, label='Limb 2 Flux')
|
90 |
+
ax.plot(self.simulation_times, self.indmodel_flux3, label='Limb 3 Flux')
|
91 |
+
ax.set_xlabel('Time (s)')
|
92 |
+
ax.set_ylabel('Flux (Weber)')
|
93 |
+
ax.set_yscale('log', base=10)
|
94 |
+
ax.legend()
|
95 |
+
ax.set_title('Flux in Each Limb Over Time (Log-Scale)')
|
96 |
+
st.pyplot(fig)
|
97 |
+
|
98 |
+
def plot_inductor_currents(self):
|
99 |
+
fig, ax = plt.subplots(figsize=(12, 8))
|
100 |
+
ax.plot(self.simulation_times, self.inductor_currents, label='Inductor Current')
|
101 |
+
ax.set_xlabel('Time (s)')
|
102 |
+
ax.set_ylabel('Current (Amperes)')
|
103 |
+
ax.legend()
|
104 |
+
ax.set_title('Inductor Current Over Time')
|
105 |
+
st.pyplot(fig)
|
106 |
+
|
107 |
+
def plot_inductor_currents_log_base_10(self):
|
108 |
+
fig, ax = plt.subplots(figsize=(12, 8))
|
109 |
+
ax.plot(self.simulation_times, self.inductor_currents, label='Inductor Current')
|
110 |
+
ax.set_xlabel('Time (s)')
|
111 |
+
ax.set_ylabel('Current (Amperes)')
|
112 |
+
ax.set_yscale('log', base=10)
|
113 |
+
ax.legend()
|
114 |
+
ax.set_title('Inductor Current Over Time (Log-Scale)')
|
115 |
+
st.pyplot(fig)
|
116 |
+
|
117 |
+
def plot_results(self):
|
118 |
+
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8))
|
119 |
+
ax1.plot(self.simulation_times, self.inductor_flux_linkages, label='Flux Linkage')
|
120 |
+
ax1.set_xlabel('Time (s)')
|
121 |
+
ax1.set_ylabel('Flux Linkage')
|
122 |
+
ax1.legend()
|
123 |
+
ax1.set_title('Flux Linkage Over Time')
|
124 |
+
|
125 |
+
ax2.plot(self.simulation_times, self.inductor_emfs, label='Induced EMF', color='red')
|
126 |
+
ax2.set_xlabel('Time (s)')
|
127 |
+
ax2.set_ylabel('EMF')
|
128 |
+
ax2.legend()
|
129 |
+
ax2.set_title('Induced EMF Over Time')
|
130 |
+
plt.tight_layout()
|
131 |
+
st.pyplot(fig)
|
132 |
+
|
133 |
+
def plot_results_log_base_10(self):
|
134 |
+
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8))
|
135 |
+
ax1.plot(self.simulation_times, self.inductor_flux_linkages, label='Flux Linkage')
|
136 |
+
ax1.set_xlabel('Time (s)')
|
137 |
+
ax1.set_ylabel('Flux Linkage')
|
138 |
+
ax1.set_yscale('log', base=10)
|
139 |
+
ax1.legend()
|
140 |
+
ax1.set_title('Flux Linkage Over Time (Log-Scale)')
|
141 |
+
|
142 |
+
ax2.plot(self.simulation_times, self.inductor_emfs, label='Induced EMF', color='red')
|
143 |
+
ax2.set_xlabel('Time (s)')
|
144 |
+
ax2.set_ylabel('EMF')
|
145 |
+
ax2.set_yscale('log', base=10)
|
146 |
+
ax2.legend()
|
147 |
+
ax2.set_title('Induced EMF Over Time (Log-Scale)')
|
148 |
+
plt.tight_layout()
|
149 |
+
st.pyplot(fig)
|
150 |
+
|
151 |
+
def plot_phi_values(self):
|
152 |
+
fig, ax = plt.subplots(figsize=(12, 8))
|
153 |
+
ax.plot(self.simulation_times, self.phi_values, label='Phi Values')
|
154 |
+
ax.set_xlabel('Time (s)')
|
155 |
+
ax.set_ylabel('Phi (Weber)')
|
156 |
+
ax.legend()
|
157 |
+
ax.set_title('Phi Values Over Time')
|
158 |
+
st.pyplot(fig)
|
159 |
+
|
160 |
+
def plot_phi_values_log_base_10(self):
|
161 |
+
fig, ax = plt.subplots(figsize=(12, 8))
|
162 |
+
ax.plot(self.simulation_times, self.phi_values, label='Phi Values')
|
163 |
+
ax.set_xlabel('Time (s)')
|
164 |
+
ax.set_ylabel('Phi (Weber)')
|
165 |
+
ax.set_yscale('log', base=10)
|
166 |
+
ax.legend()
|
167 |
+
ax.set_title('Phi Values Over Time (Log-Scale')
|
168 |
+
st.pyplot(fig)
|
169 |
+
|
170 |
+
# Streamlit App
|
171 |
+
def main():
|
172 |
+
st.title('Multi-Limb Core Model Simulation')
|
173 |
+
|
174 |
+
# Input parameters
|
175 |
+
no_of_turns = st.number_input('Number of Turns',min_value=125, max_value=777 value=500)
|
176 |
+
cs_area = st.number_input('Cross-Sectional Area', value=9.0e-4)
|
177 |
+
lengths = {
|
178 |
+
'a': st.number_input('Length a', min_value=1.0e-2, max_value=25.0e-2, value=5.0e-2),
|
179 |
+
'b': st.number_input('Length b', min_value=1.125e-2, max_value=28.8e-2,value=4.5e-2),
|
180 |
+
'c': st.number_input('Length c', min_value=0.50e-2, max_value=88.4e-2, value=4.0e-2),
|
181 |
+
'w': st.number_input('Length w', min_value=0.625e-2, max_value=100e-2,value=3.0e-2)
|
182 |
+
}
|
183 |
+
length_lg_2 = st.number_input('Length lg_2', value=0.1e-3)
|
184 |
+
mu_r = st.number_input('Relative Permeability', value=1000.0)
|
185 |
+
r = st.number_input('Resistance', min_value=0.01, max_value=0.99, value=0.01)
|
186 |
+
series_res = st.number_input('Series Resistance',min_value=2, max_value=22, value=10)
|
187 |
+
vmeas = st.number_input('Voltage Measurement', min_value=5, max_value=100,value=100)
|
188 |
+
simulation_time = st.number_input('Simulation Time', min_value=0.001, max_value=0.012,value=0.001)
|
189 |
+
|
190 |
+
if st.button('Run Simulation'):
|
191 |
+
model = MultiLimbCoreModel(no_of_turns, cs_area, lengths, length_lg_2, mu_r, r, series_res)
|
192 |
+
t_clock = 0
|
193 |
+
while t_clock < simulation_time:
|
194 |
+
model.update(vmeas, t_clock)
|
195 |
+
t_clock += model.dt
|
196 |
+
|
197 |
+
st.subheader('Results')
|
198 |
+
model.plot_reluctances_of_each_limb()
|
199 |
+
model.plot_inductor_currents()
|
200 |
+
model.plot_results()
|
201 |
+
model.plot_phi_values()
|
202 |
+
|
203 |
+
if __name__ == '__main__':
|
204 |
+
main()
|