在使用scipy.integrate.odeint求解ODE系统时合并实际数据

时间:2013-09-13 12:44:58

标签: python scipy odeint

我正在尝试构建一个由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)

2 个答案:

答案 0 :(得分:0)

这是一段时间以前,我的知识已经发生了很大的变化......

答案是你必须在你想要使用的外部数据的每一步解决ODE,使用在新状态开始时先前集成的结果。

答案 1 :(得分:0)

缺少一行,未定义qonoff。

Qonoff = zeros(len(timeline))
qonoff = [timeline, zeros(len(timeline))]
temps = Solve(timeline, qonoff)

这还不是一个解决方案,只是一个评论。