简体   繁体   English

模拟耦合常微分方程

[英]Simulate a coupled ordinary differential equation

I want to write a program which turns a 2nd order differential equation into two ordinary differential equations but I don't know how I can do that in Python.我想编写一个程序,将二阶微分方程转换为两个常微分方程,但我不知道如何在 Python 中做到这一点。

I am getting lots of errors, please help in writing the code correctly.我收到很多错误,请帮助正确编写代码。

from scipy.integrate import solve_ivp
import matplotlib.pyplot as plt
import numpy as np

N = 30          # Number of coupled oscillators.
alpha=0.25
A = 1.0 

# Initial positions.
y[0] = 0        # Fix the left-hand side at zero.
y[N+1] = 0      # Fix the right-hand side at zero.
# The range(1,N+1) command only prints out [1,2,3, ... N].
for p in range(1, N+1):    # p is particle number.
    y[p] = A * np.sin(3 * p * np.pi /(N+1.0))

####################################################
# Initial velocities.
####################################################
v[0]   = 0               # The left and right boundaries are
v[N+1] = 0               # clamped and don't move.
# This version sets them all the particle velocities to zero.
for p in range(1, N+1):
    v[p] = 0

w0 = [v[p], y[p]]
def accel(t,w):
    v[p], y[p] = w
    global a
    a[0] = 0.0
    a[N+1] = 0.0

    # This version loops explicitly over all the particles.
    for p in range(1,N+1):
        a[p] = [v[p], y(p+1)+y(p-1)-2*y(p)+ alpha * ((y[p+1] - y[p])**2 - (y[p] - y[p-1])**2)] 
    return a

   
duration = 50
t = np.linspace(0, duration, 800) 
abserr = 1.0e-8
relerr = 1.0e-6

solution = solve_ivp(accel, [0, duration], w0, method='RK45', t_eval=t, 
    vectorized=False, dense_output=True, args=(),  atol=abserr, rtol=relerr)

Most general-purpose solvers do not do structured state objects.大多数通用求解器不执行结构化 state 对象。 They just work with a flat array as representation of the state space points.它们只使用平面数组作为 state 空间点的表示。 From the construction of the initial point you seem to favor the state space ordering从最初的构造来看,您似乎更喜欢 state 空间排序

  [ v[0], v[1], ... v[N+1], y[0], y[1], ..., y[N+1] ]

This allows to simply split both and to assemble the derivatives vector from the velocity and acceleration arrays.这允许从速度和加速度 arrays 简单地拆分和组装导数向量。

Let's keep things simple and separate functionality in small functions让我们在小函数中保持简单和独立的功能

a = np.zeros(N+2)
def accel(y):
    global a ## initialized to the correct length with zero, avoids repeated allocation
    a[1:-1] = y[2:]+y[:-2]-2*y[1:-1] + alpha*((y[2:]-y[1:-1])**2-(y[1:-1]-y[:-2])**2)
    return a

def derivs(t,w):
    v,y = w[:N+2], w[N+2:]
    return np.concatenate([accel(y), v])

or keeping the theme of avoiding allocations或保持避免分配的主题

dwdt = np.zeros(2*N+4)
def derivs(t,w):
    global dwdt
    v,y = w[:N+2], w[N+2:]
    dwdt[:N+2] = accel(y)
    dwdt[N+2:] = v
    return dwdt

Now you only need to set现在你只需要设置

w0=np.concatenate([v,y])

to rapidly get to a more interesting class of errors.快速找到更有趣的 class 错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM