整合多自由度运动方程

时间:2015-10-13 14:15:29

标签: python scipy ode integrate

我想找到一个由ODE定义的具有2个自由度的简单动力系统的响应:m ddx(t) + k ddx(t) = f(t)。系统在第1点用力f1 = f01 * sin(omega*t)激发:

2 degree of freedom dynamic system

质量和刚度矩阵定义如下:

import numpy as np

m1 = 10
m2 = 8

k1 = 1e6
k2 = 3e6
k3 = 7e6

m = np.diag([m1,m2])
k = np.array([[k1 + k2, -k2],
              [-k2, k2 + k3]])

omega = 500  # excitation angular frequency

质量矩阵逆:

minv = np.linalg.inv(m)

集成功能:

def cantilever_beam_ode_with_external_excitation(t, initial_state):
    """
    ODE for a cantilever beam with external excitation (force())
    EoM: m ddx + k x = f
    """
    # unpack the state vector
    x = initial_state[0]  # vector
    xd = initial_state[1]  # vector, unimportant, since no damping

    f = force(t)

    xdd = minv.dot(-k.dot(x) + f)

    # return the two state derivatives
    return [xd, xdd]

def force(t):
    force = np.zeros(m.shape[0])
    f0 = 100
    force[0] = f0 * np.sin(omega*t)
    return force

集成参数和集成:

# initial conditions
x0 = np.zeros(m.shape[0])
dx0 = np.zeros(m.shape[0])
initial_state = (x0, dx0)

integrator = 'vode'
state_ode_f = integrate.ode(cantilever_beam_ode_with_external_excitation)
state_ode_f.set_integrator(integrator, nsteps=500, rtol=1e-3, atol=1e-5, first_step=1e-2)

t_start = 0
t_final = 1

state_ode_f.set_initial_value(initial_state, t_start)

time = np.array([t_start])
velocity = np.expand_dims(initial_state[0], axis=0)
acceleration = np.expand_dims(initial_state[1], axis=0)

print("#\t Time\t\t Timestep \t state_ode_f.successful()")
i = 1

while state_ode_f.t < (t_final):
    state_ode_f.integrate(t_final, step=True)
    time = np.append(time, state_ode_f.t)
    velocity = np.append(velocity, np.expand_dims(state_ode_f.y[0], axis=0), axis=0)
    acceleration = np.append(acceleration, np.expand_dims(state_ode_f.y[1], axis = 0), axis=0)
    print("{0} \t {1:0.5f}\t {2:0.4e} \t {3}".format(i, state_ode_f.t, time[-1] - time[-2], state_ode_f.successful()))
    i += 1

我收到以下消息:

C:\Anaconda3\python.exe D:/faks/LADISK/python/CMS_sparse/integrators/FEM_simple.py
C:\Anaconda3\lib\site-packages\scipy\integrate\_ode.py:853: UserWarning: vode: Illegal input detected. (See printed message.)
#    Time        Timestep    state_ode_f.successful()
  'Unexpected istate=%s' % istate))
4500     0.00000     0.0000e+00      False
 DVODE--  RWORK length needed, LENRW (=I1), exceeds LRW (=I2)
      In above message,  I1 =       116   I2 =        52
4501     0.00000     0.0000e+00      False
 DVODE--  RWORK length needed, LENRW (=I1), exceeds LRW (=I2)
      In above message,  I1 =       116   I2 =        52
4502     0.00000     0.0000e+00      False
 DVODE--  RWORK length needed, LENRW (=I1), exceeds LRW (=I2)
      In above message,  I1 =       116   I2 =        52
4503     0.00000     0.0000e+00      False
 DVODE--  RWORK length needed, LENRW (=I1), exceeds LRW (=I2)
      In above message,  I1 =       116   I2 =        52
...

欢迎任何有关如何解决问题的想法。

谢谢!

1 个答案:

答案 0 :(得分:1)

我认为问题在于您将状态定义为数组的列表(或元组)(每个3个元素)。另一方面,XDocument需要一个标量,数组或列表(标量)。

我可以通过将状态转换为1个更长的数组来运行它(但不能保证值是正确的):

ode

用一个重塑和重新组合结果的函数包装你的函数

state_array = np.hstack(initial_state)

产生如下值:

def fn(t, state):
    # try raveled state
    state = state.reshape((2,-1))
    dd = cantilever_beam_ode_with_external_excitation(t, state)
    return np.hstack(dd)

state_ode_f = integrate.ode(fn)
state_ode_f.set_integrator(integrator, nsteps=500, rtol=1e-3, atol=1e-5, first_step=1e-2)

t_start = 0
t_final = 1
delta_t = 0.1

state_ode_f.set_initial_value(state_array, t_start)

for i  in range(20):
    state_ode_f.integrate(t_final, step=True)
    print(i,state_ode_f.t)
    print(state_ode_f.y.reshape((2,-1)))