我正在尝试构建一个由 ODE 系统表示并使用 scipy 的 odeint 函数解决的加热系统的简单模型。
我想在这个模型中加入“真实”数据,例如外部温度(在下面模拟为正弦波)。下面的代码显示了我当前的解决方案/hack,它使用一个名为 FindVal 的函数将真实数据插入到由 odeint 评估的时间戳。
这非常慢,所以我正在寻找有关如何以更好的方式完成此操作的建议。
这是代码...
from scipy.integrate import odeint
from numpy import linspace
from numpy import interp
from numpy import sin
from numpy.random import randint
from numpy import array
from numpy import zeros
from numpy import where
def FindVal(timeseries, t):
''' finds the value of a timeseries at the time given by the ode solver
INPUTS: timeseries - [list of times, list of values]
t - timestamp being evaluated
OUTPUTS: interpolated value at t
'''
ts_t = timeseries[0]
ts_v = timeseries[1]
# if t is beyond the end of the time series chose the last value
if t > ts_t[-1]:
val = ts_v[-1]
else:
val = interp(t, ts_t, ts_v)
return val
def SpaceHeat(Tin, t):
''' calculates the change in internal temperature
INPUTS: Tin - temperature at t - 1
t - timestep
OUTPUTS: dTdt - change in T
'''
# unpack params
ma = params['ma'] # mass of air
ca = params['ca'] # heat capacity of air
hlp = params['hlp'] # heat loss parameter
qp = params['qp'] # heater power
Touts = params['Tout'] # list of outside temps
Tout = FindVal(Touts, t) # value of Tout in this timestep
Qonoffs = params['Qonoff'] # list of heater on/offs
Qonoff = FindVal(Qonoffs, t) # heater state at this timestep
qin = qp * Qonoff # heat input
qmass = 0 # ignore mass effects for now
# calculate energy lost
qloss = (Tin - Tout) * hlp #
# calculate the change in temperature
dTdt = (qin - qmass - qloss) / (ma * ca)
return dTdt
def Solve(timeline, Qonoff):
# simulate the outside temp as a sinewave
Tout = [timeline, (sin(0.001 * timeline + 1500) * 10) + 2] # outside temp
# create a dict of model parameters
global params
params = {'ma' : 1000.0 * 250, # air mass, kg
'ca' : 1.0, # air heat capacity j/kg
'hlp' : 200.0, # home heat loss parameter wk
'qp' : 10000.0, # heater output w
'Qonoff' : Qonoff, # list of on off events
'Tout' : Tout,
}
# set the initial temperature
Tinit = 10.0
# solve
temps = odeint(SpaceHeat, Tinit, timeline)
return temps
# create a timeline for the simulation
timeline = linspace(0, 6000, 96)
# calculate the optimum control
Qonoff = zeros(len(timeline))
temps = Solve(timeline, qonoff)