Python物理学有限差分微分求解器和动画波形传播

27 篇文章 0 订阅
11 篇文章 1 订阅

🎯要点

Python数值和符号计算:

  1. 振动常微分方程:🎯中心差分求解器,绘制移动窗口研究长时间序列。🎯符号计算离散方程量化误差。🎯Python数值对比正向欧拉方法,反向欧拉方法,克兰克-尼科尔森方法和龙格-库塔法解。🎯数值计算振动能量数值收敛。🎯欧拉-克罗默方法求解器。🎯交错网格法求解器。🎯使用线性/二次函数和符号计算验证常微分方程。🎯线性/二次阻尼求解器和验证函数,绘制阻尼正弦函数图。🎯绘制钟摆动态自由体图模拟,创建求解器计算。🎯模拟弹性摆。
  2. 波形运动偏微分方程:🎯弹簧波形模拟:方程算式转换,制定递归算法,代码实现数值求解器,结果动画演示,二次解和敛率的验证函数。示例:创建吉他弦一维波形方程数值求解器,动画模拟弦振动波形。🎯反射边界的诺依曼条件,代码实现一维波形方程,验证函数检测结果。🎯可变波速,代码实现可变系数。🎯代码实现给定条件下,通用一维波形方程求解器。🎯差分方程正弦和余弦波分析,代码实现网格,离散傅里叶变换,计算对应频率。🎯对离散化参数进行泰勒级数展开,代码计算数值色散关系,代码计算二维数值色散关系并绘制二维数值色散误差结果图。🎯代码解二维线性波形方程,矢量化计算函数代码,高斯函数绘制波形在正方形中传播。
  3. 扩散偏微方程:🎯代码实现具有边界条件的一维扩散求解器,代码验证求解器,动画可视化正向欧拉结果。🎯实现前向欧拉算法和稳定条件下一维求解器,实现求解器矢量化函数 🎯一维扩散方程隐性方法:代码实现反向欧拉法求解器,及其矢量化函数。🎯二维和三维扩散方程求解器。🎯异质介质中的扩散离散化后:代码实现求解器,稀疏矩阵处理。🎯分段恒定介质中扩散的代码实现,绘图可视化恒定扩散系数结果。🎯实现稠密系数矩阵求解器,数值验证。🎯代码实现稀疏稀疏矩阵计算。🎯雅可比方法代码实现,解线性系统。
  4. 平流方程,非线性问题

🍇Python热方程有限差分计算示例

热方程基本上是一个偏微分方程,即:
∂ u ∂ t − α ∇ u = 0 \frac{\partial u}{\partial t}-\alpha \nabla u=0 tuαu=0
如果我们想用二维(笛卡尔)求解,我们可以这样写上面的热方程
∂ u ∂ t − α ( ∂ 2 u ∂ x + ∂ 2 u ∂ y ) = 0 \frac{\partial u}{\partial t}-\alpha\left(\frac{\partial^2 u}{\partial x}+\frac{\partial^2 u}{\partial y}\right)=0 tuα(x2u+y2u)=0
其中 u u u是我们想要知道的数量, t t t是时间变量, x x x y y y是空间变量, α \alpha α是扩散常数。所以基本上我们希望在 x x x y y y 中的任何地方以及随着时间的 t t t 找到解决方案 u u u。现在让我们简单地了解一下有限差分法。有限差分法是一种通过有限差分逼近导数来求解微分方程的数值方法。请记住导数的定义是:
f ′ ( a ) = lim ⁡ h → 0 f ( a + h ) − f ( a ) h f^{\prime}(a)=\lim _{h \rightarrow 0} \frac{f(a+h)-f(a)}{h} f(a)=h0limhf(a+h)f(a)
在有限差分法中,我们对其进行近似并去除限制。 因此,我们不使用微分和极限符号,而是使用 delta 符号,即有限差分。 请注意,这过于简单化了,因为我们必须使用泰勒级数展开,并通过假设某些项足够小来推导出它,但我们得到了该方法背后的粗略想法。
f ′ ( a ) ≈ f ( a + h ) − f ( a ) h f^{\prime}(a) \approx \frac{f(a+h)-f(a)}{h} f(a)hf(a+h)f(a)
在有限差分方法中,我们将“离散化”空间域和时间间隔 x、y 和 t。我们可以这样写
x i = i Δ x y j = j Δ y t k = k Δ t \begin{aligned} &x_i=i \Delta x\\ &y_j=j \Delta y\\ &t_k=k \Delta t \end{aligned} xi=iΔxyj=jΔytk=kΔt
正如我们所看到的, i 、 j i、j ij k k k 分别是 x 、 y x、y xy t t t 的每个差异的步骤。我们想要的是解 u u u,即
u ( x , y , t ) = u i , j k u(x, y, t)=u_{i, j}^k u(x,y,t)=ui,jk
请注意, k k k 是上标,表示 u u u 的时间步长。我们可以使用有限差分法写出上面的热方程,如下所示
u i , j k + 1 − u i , j k Δ t − α ( u i + 1 , j k − 2 u i , j k + u i − 1 , j k Δ x 2 + u i , j + 1 k − 2 u i , j k + u i , j − 1 k Δ y 2 ) = 0 \frac{u_{i, j}^{k+1}-u_{i, j}^k}{\Delta t}-\alpha\left(\frac{u_{i+1, j}^k-2 u_{i, j}^k+u_{i-1, j}^k}{\Delta x^2}+\frac{u_{i, j+1}^k-2 u_{i, j}^k+u_{i, j-1}^k}{\Delta y^2}\right)=0 Δtui,jk+1ui,jkα(Δx2ui+1,jk2ui,jk+ui1,jk+Δy2ui,j+1k2ui,jk+ui,j1k)=0
如果我们通过 Δ x = Δ y \Delta x=\Delta y Δx=Δy 排列上面的方程,我们得到最终的方程
u i , j k + 1 = γ ( u i + 1 , j k + u i − 1 , j k + u i , j + 1 k + u i , j − 1 k − 4 u i , j k ) + u i , j k u_{i, j}^{k+1}=\gamma\left(u_{i+1, j}^k+u_{i-1, j}^k+u_{i, j+1}^k+u_{i, j-1}^k-4 u_{i, j}^k\right)+u_{i, j}^k ui,jk+1=γ(ui+1,jk+ui1,jk+ui,j+1k+ui,j1k4ui,jk)+ui,jk
其中, γ = α Δ t Δ x 2 \gamma=\alpha \frac{\Delta t}{\Delta x^2} γ=αΔx2Δt

对于我们的模型,我们取 Δ x = 1 \Delta x=1 Δx=1 α = 2.0 \alpha=2.0 α=2.0。现在我们可以使用 Python 代码以数值方式解决这个问题,以查看各处的温度(用 i i i j j j 表示)和随时间变化的温度(用 k k k 表示)。我们首先导入所有必要的库,然后设置边界和初始条件。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib.animation import FuncAnimation

plate_length = 50
max_iter_time = 1000

alpha = 2.0
delta_x = 1

delta_t = (delta_x ** 2)/(4 * alpha)
gamma = (alpha * delta_t) / (delta_x ** 2)

u = np.empty((max_iter_time, plate_length, plate_length))

u_initial = 0.0

u_top = 100.0
u_left = 0.0
u_bottom = 0.0
u_right = 0.0

u.fill(u_initial)

u[:, (plate_length-1):, :] = u_top
u[:, :, :1] = u_left
u[:, :1, 1:] = u_bottom
u[:, :, (plate_length-1):] = u_right

我们已经设置了初始条件和边界条件,让我们根据上面推导的有限差分方法编写计算函数。

def calculate(u):
  for k in range(0, max_iter_time-1, 1):
    for i in range(1, plate_length-1, delta_x):
      for j in range(1, plate_length-1, delta_x):
        u[k + 1, i, j] = gamma * (u[k][i+1][j] + u[k][i-1][j] + u[k][i][j+1] + u[k][i][j-1] - 4*u[k][i][j]) + u[k][i][j]
  
  return u

让我们准备绘图函数,以便我们可以将解(对于每个 k)可视化为热图。我们使用Matplotlib库,它很容易使用。

参阅一:计算思维
参阅二:亚图跨际
  • 16
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
有限差分法是求解微分方程的常用方法之一,它将偏微分方程中的求导操作离散化为差分运算,从而将偏微分方程转化为一个差分方程,然后通过迭代求解差分方程,得到偏微分方程的数值解。 对于一个二阶偏微分方程: $$\frac{\partial^2 u}{\partial x^2} + \frac{\partial^2 u}{\partial y^2} = f(x,y)$$ 其中 $u=u(x,y)$,$f=f(x,y)$,我们可以采用有限差分法进行求解。具体的方法是将求导操作离散化为差分运算,即: $$\frac{\partial^2 u}{\partial x^2} \approx \frac{u_{i+1,j}-2u_{i,j}+u_{i-1,j}}{(\Delta x)^2}$$ $$\frac{\partial^2 u}{\partial y^2} \approx \frac{u_{i,j+1}-2u_{i,j}+u_{i,j-1}}{(\Delta y)^2}$$ 其中 $u_{i,j}=u(x_i,y_j)$,$\Delta x$ 和 $\Delta y$ 分别为 $x$ 和 $y$ 的步长。 代入原方程,得到差分方程: $$\frac{u_{i+1,j}-2u_{i,j}+u_{i-1,j}}{(\Delta x)^2} + \frac{u_{i,j+1}-2u_{i,j}+u_{i,j-1}}{(\Delta y)^2} = f_{i,j}$$ 通过对差分方程进行离散化,可以得到一个线性方程组,使用迭代方法求解该线性方程组即可得到偏微分方程的数值解。 以下是一个简单的 Python 代码实现: ```python import numpy as np def solve_pde(f, a, b, c, d, nx, ny, max_iter=1000, tol=1e-6): """ 用有限差分求解二维偏微分方程 f: 函数 f(x,y) a,b,c,d: 区域 [a,b]x[c,d] 的边界条件 nx,ny: 离散化后网格的数量 max_iter: 最大迭代次数 tol: 收敛精度 """ dx = (b-a) / (nx-1) dy = (d-c) / (ny-1) x = np.linspace(a, b, nx) y = np.linspace(c, d, ny) u = np.zeros((nx, ny)) # 边界条件 u[0, :] = [a(x[i], y[0]) for i in range(nx)] u[nx-1, :] = [b(x[i], y[ny-1]) for i in range(nx)] u[:, 0] = [c(x[0], y[j]) for j in range(ny)] u[:, ny-1] = [d(x[nx-1], y[j]) for j in range(ny)] # 迭代求解 for k in range(max_iter): u_old = u.copy() for i in range(1, nx-1): for j in range(1, ny-1): u[i,j] = (u_old[i+1,j] + u_old[i-1,j]) / dx**2 \ + (u_old[i,j+1] + u_old[i,j-1]) / dy**2 \ - f(x[i], y[j]) / (dx**2 + dy**2) if np.linalg.norm(u - u_old) < tol: break return u ``` 其中,`f` 表示方程中的右侧项,`a`、`b`、`c`、`d` 分别表示边界条件,`nx` 和 `ny` 分别表示对 $x$ 和 $y$ 离散化后的网格数量,`max_iter` 和 `tol` 分别表示最大迭代次数和收敛精度。通过调用 `solve_pde` 函数即可求解微分方程的数值解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值