|
|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
在网上找了个算例,解二维抛物线偏微分方程,按算法跑了1600步,结果精确值为0的地方变成0.002几。但我看算例上用MATLAB做,计算值才10^-16。为什么差别这么大呢,是我的代码有问题还是,需要用什么方法提高PYTHON的精度呢?
希望有大神可以解惑!
附上自己的代码和算例链接
- # -*- coding: utf-8 -*-
- """
- Created on Fri Nov 8 18:04:41 2019
- @author: Administrator
- """
- from __future__ import division
- import numpy as np
- import math
- import matplotlib.pyplot as plt
- #计算初始U(j,k)
- h = 1/40 #空间步长
- t = 1/1600 #空间步长
- #a2 = 1/16 #系数
- miu = t/h**2
- F1 = np.zeros((38,38))
- F2 = np.zeros((40,40))
- def doit():
- a1,b1,c1 = construct_step1_A()
- a2,b2,c2 = construct_step2_A()
- U0 = initialize()
- T = 0
- er = []
- while T<30:
- Uhalf = forward_half_1(a1,b1,c1,U0)
- U1 = forward_half_2(a2,b2,c2,Uhalf)
- U0 = U1
- T += 1
- return U0
- #计算精确值
- def realsolve(j,k,t):
- return math.sin(math.pi*j*h)*math.cos(math.pi*k*h)*math.e**(-math.pi**2/8*t)
- def initialize():
- U = np.zeros((40,40))
- for i in range(40):
- for j in range(40):
- U[i,j] = realsolve(i,j,0)
-
- return U
- #追赶法求解
- def thomas_solve(a,b,c,f):
- x = np.zeros_like(f)
- y = np.zeros_like(f)
- u = np.zeros_like(f)
- l = np.zeros((len(f)-1,1))
- u[0] = b[0]
- for i in range(1,len(f)):
- l[i-1] = a[i-1]/u[i-1]
- u[i] = b[i] - l[i-1]*c[i-1]
-
- y[0] = f[0]
- for i in range(1,len(f)):
- y[i] = f[i] - l[i-1] * y[i-1]
-
- x[len(x)-1] = y[len(x)-1]/u[len(x)-1]
- for i in range(len(x)-2,-1,-1):
- x[i] = (y[i] - c[i]*x[i+1])/u[i]
-
- return x
-
-
- #初始化第一步A矩阵
- def construct_step1_A():
- a = np.ones((37,1))*(-1/32*miu)
- c = np.ones((37,1))*(-1/32*miu)
- b = np.ones((38,1))*(1+1/16*miu)
-
- return a,b,c
-
- def construct_step2_A():
- a = np.ones((39,1))*(-1/32*miu)
- c = np.ones((39,1))*(-1/32*miu)
- b = np.ones((40,1))*(1+1/16*miu)
-
- b[0] = 1
- b[39] = 1
- c[0] = -1
- a[38] = -1
-
- return a,b,c
-
- #初始化0时刻向量矩阵F
- def construct_step1_F(U0):
- for j in range(38):
- for k in range(38):
- F1[j,k] = miu/32*(U0[j+1,k+1-1] - 2*U0[j+1,k+1] + U0[j+1,k+1+1]) + U0[j+1,k+1]
-
- return F1
- def construct_step2_F(U1):
- for j in range(1,39):
- for k in range(1,39):
- F2[j,k] = miu/32*(U1[j-1,k] - 2*U1[j,k] + U1[j+1,k]) +U1[j,k]
-
- return F2
- def forward_half_1(a1,b1,c1,U0):
- F1 = construct_step1_F(U0)
- Uhalf = np.zeros_like(U0)
- for k in range(1,Uhalf.shape[0]-1):
- Uhalf[1:Uhalf.shape[0]-1,k] = thomas_solve(a1,b1,c1,F1[:,k-1])
- return Uhalf
- def forward_half_2(a2,b2,c2,Uhalf):
- F2 = construct_step2_F(Uhalf)
- U1 = np.zeros_like(Uhalf)
- for j in range(U1.shape[0]):
- U1[j,:] = thomas_solve(a2,b2,c2,F2[j,:])
-
- return U1
-
-
复制代码 算例地址 |
|