Проблема заключается в том, что dydt
, который вы создаете, все еще содержит выражения sympy со свободными символами.Я предполагаю, что ваше намерение с предыдущими назначениями в функции состоит в том, чтобы установить символы во всех выражениях sympy, используя их.Однако назначение в Python является привязкой имени.На самом деле вы просто привязываете вычисленные значения к именам, которые (кстати, в другой функции) были привязаны к символам sympy.
Вам нужно фактически подставить значения в выражение sympy.Быстро и грязно:
dydt = [x[0].subs(locals()) for x in p_I_matrix]
Замените locals()
на словарь, составленный из всех заданий, которые вы сделали ранее, чтобы сделать это чище.
Вот функция model
с быстрым решением:
def model(y, t):
ias = y[0]
ibs = y[1]
ics = y[2]
iar_r = y[3]
ibr_r = y[4]
icr_r = y[5]
alpha = 480.0 / 208
vas = (480.0/m.sqrt(3))*m.sqrt(2)*m.cos(377*t-30*m.pi/180)
vbs = (480.0/m.sqrt(3))*m.sqrt(2)*m.cos(377*t-150*m.pi/180)
vcs = (480.0/m.sqrt(3))*m.sqrt(2)*m.cos(377*t-270*m.pi/180)
ZL1_r = 10.0 * alpha ** 2
ZL2_r = 10.0 * alpha ** 2
ZL3_r = 10.0 * alpha ** 2
return [x[0].subs(locals()) for x in p_I_matrix]
Это работает как задумано и заменяет все переменные, локальные для области действия функции (те, которые назначены в функции), если они соответствуют именам символов sympy внутри выражений.Понимание списка значительно упрощает код (и на самом деле его также следует использовать для всех пронумерованных переменных).
Можно сказать, что использование locals()
таким способом не очень чисто, поскольку может заменить любой символв выражении sympy, если случается несвязанное использование локальной переменной с тем же именем.Поэтому лучше явно указать список символов для замены:
def model(y, t):
ias = y[0]
ibs = y[1]
ics = y[2]
iar_r = y[3]
ibr_r = y[4]
icr_r = y[5]
alpha = 480.0 / 208
vas = (480.0/m.sqrt(3))*m.sqrt(2)*m.cos(377*t-30*m.pi/180)
vbs = (480.0/m.sqrt(3))*m.sqrt(2)*m.cos(377*t-150*m.pi/180)
vcs = (480.0/m.sqrt(3))*m.sqrt(2)*m.cos(377*t-270*m.pi/180)
ZL1_r = 10.0 * alpha ** 2
ZL2_r = 10.0 * alpha ** 2
ZL3_r = 10.0 * alpha ** 2
subs_dict = {
'ias': ias,
'ibs': ibs,
'ics': ics,
'iar_r': iar_r,
'ibr_r': ibr_r,
'icr_r': icr_r,
'vas': vas,
'vbs': vbs,
'vcs': vcs,
'ZL1_r': ZL1_r,
'ZL2_r': ZL2_r,
'ZL3_r': ZL3_r
}
return [x[0].subs(subs_dict) for x in p_I_matrix]
Версия без симпита, потому что она намного эффективнее:
def make_model(Lls=0.3,Lms=3.0,Llr_r=0.3,rp=1.0,rs=1.0):
alpha = 480.0 / 208
L = np.array([[Lls+Lms, -0.5*Lms, -0.5*Lms, Lms, -0.5*Lms, -0.5*Lms],
[-0.5*Lms, Lls+Lms, -0.5*Lms, -0.5*Lms, Lms, -0.5*Lms],
[-0.5*Lms, -0.5*Lms, Lls+Lms, -0.5*Lms, -0.5*Lms, Lms],
[Lms, -0.5*Lms, -0.5*Lms, Llr_r+Lms, -0.5*Lms, -0.5*Lms],
[-0.5*Lms, Lms, -0.5*Lms, -0.5*Lms, Llr_r+Lms, -0.5*Lms],
[-0.5*Lms, -0.5*Lms, Lms, -0.5*Lms, -0.5*Lms, Llr_r+Lms]])
def model(y, t):
ias = y[0]
ibs = y[1]
ics = y[2]
iar_r = y[3]
ibr_r = y[4]
icr_r = y[5]
vas = (480.0/m.sqrt(3))*m.sqrt(2)*m.cos(377*t-30*m.pi/180)
vbs = (480.0/m.sqrt(3))*m.sqrt(2)*m.cos(377*t-150*m.pi/180)
vcs = (480.0/m.sqrt(3))*m.sqrt(2)*m.cos(377*t-270*m.pi/180)
ZL1_r = 10.0 * alpha ** 2
ZL2_r = 10.0 * alpha ** 2
ZL3_r = 10.0 * alpha ** 2
r = np.array([[rp, 0, 0, 0, 0, 0],
[0, rp, 0, 0, 0, 0],
[0, 0, rp, 0, 0, 0],
[0, 0, 0, rs+ZL1_r, 0, 0],
[0, 0, 0, 0, rs+ZL2_r, 0],
[0, 0, 0, 0, 0, rs+ZL3_r]])
v = np.array([[vas],
[vbs],
[vcs],
[0],
[0],
[0]])
i = np.array([[ias],
[ibs],
[ics],
[iar_r],
[ibr_r],
[icr_r]])
inverse_L = np.linalg.inv(L)
p_I_matrix = np.dot(inverse_L,(v - np.dot(r,i)))
return [x[0] for x in p_I_matrix]
return model
t = np.linspace(139.5,140,1000000)
dydt = odeint(make_model(),[0,0,0,0,0,0],t) #(model, initial conditions, t)
Есть также возможности для улучшенияв этой модели функция, но она должна быть намного быстрее и легче писать / читать.