python之有限体积法求解一维热传导问题

1、问题描述

python之有限体积法求解一维热传导问题_第1张图片

考虑均匀发热无限大平板的稳定导热问题,上图中,A、B两面恒温,控制方程为如下形式:

\frac{\partial }{\partial x}\left(\Gamma {\frac{\partial \phi }{\partial x}} +S_\phi \right )=0

\Gamma为扩散系数,k为材料传热系数,给定厚度L=2cmk=5W/\left(m^2\cdot K \right )T_AT_B分别为100℃和400℃,发热量q为500kW/m^3,确定平板内的稳态温度分布?

2、基于有限体积法的公式推导

假定在y方向和z方向上尺寸无限大,温度梯度只在x方向上有意义。

把整个区域划分为4个控制体,给定\delta x=0.005m

python之有限体积法求解一维热传导问题_第2张图片

由于传热系数是常数,定义k=k_e=k_w,体机源项S_\phi =q,节点2处的一般离散形式为

a_PT_P=a_ET_E+a_WT_W+b

其中

a_E=\frac{kA}{\delta x^2}

a_W=\frac{kA}{\delta x^2}

a_P=a_E+a_W

b=p

节点3得到控制方程和节点2一样。

对于节点1和4的控制体,在边界点和临近点之间的温度,采用线性近似。

对于恒定传热系数和热流量,方程变为

k\left(\frac{\partial T}{\partial x} \right )_e-k\left(\frac{\partial T}{\partial x} \right )_w+q\delta x=0

在控制体1的左侧和右侧,引入线性梯度近似:

kA\cdot\frac{T_E-T_P}{\delta x}-kA\cdot\frac{T_P-T_A}{\delta x/2}+q\delta x=0

对于节点1,得到离散方程:

a_PT_P=a_ET_E+a_WT_W+b

其中

a_E=\frac{kA}{\delta x^2}

a_W=0

a_P=a_E+a_W+\frac{2kA}{\delta x}

b=q\delta x+\frac{2kA}{\delta x}T_A

同理,节点4的离散方程为:

a_PT_P=a_ET_E+a_WT_W+b

其中

a_E=0

a_W=\frac{kA}{\delta x^2}

a_P=a_E+a_W+\frac{2kA}{\delta x}

b=q\delta x+\frac{2kA}{\delta x}T_B

将传热系数k=5W/\left(m^2\cdot K \right ),热流量q=500kW/m^3\delta x=0.005m以及单位面积A=1m^2等系数代入离散方程,得到如下方程组:

\begin{bmatrix} 3000&-1000 &0 &0 \\ -1000&2000 &-1000 &0 \\ 0&-1000 &2000 &-1000 \\ 0&0 &-1000 &3000 \end{bmatrix}  \begin{bmatrix} T1\\ T2 \\ T3 \\T4 \end{bmatrix} =\begin{bmatrix} 2000T_A+2500\\ 2500 \\ 2500 \\2000T_B+2500 \end{bmatrix}

3、python求解分析

3.1高斯消去法

高斯消去法是一种线性代数中的算法,用于求解线性方程组。它的优点和缺点如下:

优点:

精度高:高斯消去法通过将系数矩阵化为上三角矩阵,减少了求解过程中的误差,提高了求解的精度。

稳定性好:在求解过程中,高斯消去法通过选取主元来保证计算的稳定性。主元的选取可以避免出现除数为零的情况,从而保证了计算的稳定性。

可扩展性强:高斯消去法可以很容易地扩展到求解更大规模的线性方程组。只需要增加计算机的存储空间和计算能力,就可以求解更大规模的线性方程组。

算法简单易懂:高斯消去法的求解过程可以通过手工计算来理解,也可以通过编程实现来求解。

缺点:

计算量大:高斯消去法的计算量较大,尤其是在求解大规模线性方程组时,计算量更是巨大。这会导致求解时间较长,不适合实时求解。

存储空间大:高斯消去法需要存储系数矩阵和常数向量,这会占用较大的存储空间。在求解大规模线性方程组时,存储空间的需求更是巨大。

主元选取困难:高斯消去法的主元选取对计算结果的影响很大。如果选取不当,会导致计算结果的不稳定性和精度下降。因此,主元选取是一个比较困难的问题。

无法处理奇异矩阵:如果系数矩阵是奇异矩阵,那么高斯消去法将无法求解线性方程组。

import numpy as np
def gauss(a, b):
    m, n = a.shape
    c = np.zeros(n)
    for i in range(n):
        if (a[i][i] == 0): # 用高斯消去法解线性方程组时对角线元素不能为0
            print("no answer")

# k表示第一层循环,(0,n-1)行
# i表示第二层循环,(k+1,n)行,计算该行消元的系数
# j表示列
    for k in range(n - 1):
        for i in range(k + 1, n):
            c[i] = a[i][k] / a[k][k] # 计算出系数

            for j in range(k,m): # 从K开始,减少不必要的计算
                a[i][j] = a[i][j] - c[i] * a[k][j] # 对矩阵进行高斯消去
            b[i] = b[i] - c[i] * b[k]

        print('step',k,':n',a,'n')
#print(b)
    x = np.zeros(n)

    x[n - 1] = b[n - 1] / a[n - 1][n - 1] # 解出x[n-1],为回代作准备

# 回代求出方程解
    for i in range(n-2, -1, -1):
        sum= 0.0
        for j in range(n-1, -1, -1):
            sum= sum + a[i][j] * x[j]
        x[i] = (b[i]-sum) / a[i][i]
# 输出计算结果
    for i in range(n):
        print("x" + str(i + 1) + " = ","%.2f" % x[i]) # 输出结果

if __name__ == '__main__':
    A = np.array([
        [3000, -1000, 0, 0],
        [-1000, 2000, -1000, 0],
        [0, -1000, 2000, -1000],
        [0, 0, -1000, 3000],
    ])
    b = np.array([202500, 2500, 2500, 802500])
    gauss(A, b)

step 0 :n [[ 3000 -1000     0     0]
 [    0  1666 -1000     0]
 [    0 -1000  2000 -1000]
 [    0     0 -1000  3000]] n
step 1 :n [[ 3000 -1000     0     0]
 [    0  1666 -1000     0]
 [    0     0  1399 -1000]
 [    0     0 -1000  3000]] n
step 2 :n [[ 3000 -1000     0     0]
 [    0  1666 -1000     0]
 [    0     0  1399 -1000]
 [    0     0     0  2285]] n
x1 =  140.09
x2 =  217.77
x3 =  292.81
x4 =  365.13
 

3.2TDMA算法

TDMA算法,即三对角矩阵算法,是一种用于求解具有三对角线系数矩阵的代数方程组的算法。

其优点有:

高效:TDMA算法的计算复杂度为O(n),n为方程组的大小。这意味着对于较大规模的方程组,该算法能够快速求解。

稳定性高:该算法在求解过程中,不会出现数值不稳定性或误差累积的问题。

然而,它也有一些缺点:

需要额外的存储空间:对于大规模的问题,需要额外的存储空间来存储中间计算结果。

对初值敏感:TDMA算法的收敛速度可能会受到初值的影响,如果初值选择不当,可能会导致算法不收敛或者收敛速度很慢。

需要精确计算:由于涉及到大量的浮点运算,如果硬件或者软件出现故障,可能会导致计算结果不准确。

需要专业训练:该算法需要专业训练才能理解和使用,对于非专业人员来说可能会有一定的学习难度。

import numpy as np
def tdma(A,b):
    m,n = A.shape
    p = np.zeros(m)
    q = np.zeros(n)
    phi = np.zeros(m)

    p[0] = -A[0,1]/A[0,0]
    q[0] = b[0]/A[0,0]

    for i in range(1,m):
        if i != m-1 :
            p[i] = -A[i,i+1]/(A[i,i]+A[i,i-1]*p[i-1])
        else:
            p[i]= 0
        q[i] = (b[i]-A[i,i-1]*q[i-1])/(A[i,i]+A[i,i-1]*p[i-1])

    # 回代
    phi[m-1] = q[m-1]
    for i in range(m-2,-1,-1):
        phi[i] = p[i]*phi[i+1] +q[i]

    return phi

# 测试
A = np.array([
    [3000,-1000,0,0],
    [-1000,2000,-1000,0],
    [0,-1000,2000,-1000],
    [0,0,-1000,3000],
])
b = np.array([202500,2500,2500,802500])

phi = tdma(A,b)
print(phi)

[140.  217.5 292.5 365. ]

3.3雅可比迭代法

雅可比迭代法是一种求解线性方程组的迭代方法,其优点和缺点如下:

优点:

计算公式简单:雅可比迭代法的计算公式简单明了,每迭代一次只需要计算一次矩阵和向量的乘法。

并行计算:由于在计算过程中原始矩阵始终不变,因此雅可比迭代法比较容易进行并行计算。

缺点:

收敛速度较慢:雅可比迭代法的收敛速度通常比其他一些迭代方法慢,如高斯-赛德尔迭代法或牛顿法等。

存储空间较大:雅可比迭代法需要存储方程组的系数矩阵和常数向量,因此需要较大的存储空间,这可能在处理大规模问题时成为限制。

import numpy as np
# A为系数矩阵,b为结果矩阵
# k为最大迭代次数,tol为容差限
def Jacobi(A,b,k,tol):
    n = A.shape[1]
    D = np.eye(n)
    D[np.arange(n),np.arange(n)] = A[np.arange(n),np.arange(n)]
    LU = A - D
    X = np.zeros(n)

    # 迭代k次
    for i in range(k):
        X1= X.copy()
        D_inv = np.linalg.inv(D)
        X = -np.dot(np.dot(D_inv,LU),X) + np.dot(D_inv,b)
        if (np.max(np.abs(X-X1)))<=tol:
            print('计算收敛!')
            break
        print('n第',i,'次迭代:',X)
        print('残差值为:',np.abs(X-X1))
        print('当前最大残差为:', np.max(np.abs(X-X1)))
    return X

A = np.array([
    [3000,-1000,0,0],
    [-1000,2000,-1000,0],
    [0,-1000,2000,-1000],
    [0,0,-1000,3000],
])
b = np.array([202500,2500,2500,802500])
X = Jacobi(A, b, 1000,0.005)

n第 32 次迭代: [139.99525386 217.49138441 292.48962427 364.996059  ]
残差值为: [0.00066203 0.00562283 0.00144728 0.00257203]
当前最大残差为: 0.005622829086746606
计算收敛!

3.4高斯赛德尔迭代法

高斯-赛德尔迭代法是一种求解线性方程组的迭代方法,其优点和缺点如下:

优点:

收敛速度快:高斯-赛德尔迭代法通常具有较快的收敛速度,可以在较短的时间内求解出方程组的近似解。

适用范围广:高斯-赛德尔迭代法可以适用于各种线性方程组,无论是大型稀疏矩阵还是小型稠密矩阵都可以得到较好的结果。

计算量较小:相对于其他迭代方法,高斯-赛德尔迭代法的计算量较小,因此在计算时间和内存消耗方面具有优势。

可以处理稀疏矩阵:高斯-赛德尔迭代法可以有效地处理稀疏矩阵,可以减少计算时间和内存消耗。

缺点:

对系数矩阵的条件有要求:高斯-赛德尔迭代法的收敛性与系数矩阵的条件有关,如果系数矩阵不是正定矩阵或其条件数太大,可能会导致迭代不收敛或收敛速度慢。

需要选择适当的迭代参数:高斯-赛德尔迭代法的收敛速度和计算精度与初始迭代参数的选择有关,如果参数选择不当,可能会导致迭代不收敛或收敛速度慢。

对计算机内存要求较高:当处理大型稀疏矩阵时,高斯-赛德尔迭代法需要占用大量的内存空间来存储矩阵和向量,因此对计算机内存要求较高。

import numpy as np
# A为系数矩阵,b为结果矩阵
# k为最大迭代次数,tol为容差限
def Guauss_seidel(A,b,k,tol):
    n = A.shape[1]
    D = np.eye(n)
    D[np.arange(n),np.arange(n)] = A[np.arange(n),np.arange(n)]
    LU = A - D
    # 得到LU的上、下三角矩阵
    L = np.tril(LU)
    U = np.triu(LU)
    D_L = D + L
    X = np.zeros(n)

    # 迭代k次
    for i in range(k):
        X1= X.copy()
        D_L_inv = np.linalg.inv(D_L)
        X = -np.dot(np.dot(D_L_inv,U),X) + np.dot(D_L_inv,b)

        if (np.max(np.abs(X-X1)))<=tol:
            print('计算收敛!')
            break
        print('n第',i,'次迭代:',X)
        print('残差值为:',np.abs(X-X1))
        print('当前最大残差为:', np.max(np.abs(X-X1)))
    return X

A = np.array([
    [3000,-1000,0,0],
    [-1000,2000,-1000,0],
    [0,-1000,2000,-1000],
    [0,0,-1000,3000],
])
b = np.array([202500,2500,2500,802500])
X = Guauss_seidel(A, b, 1000,0.005)

n第 17 次迭代: [139.99560885 217.49300459 292.49490235 364.99830078]
残差值为: [0.00387807 0.00617804 0.00450202 0.00150067]
当前最大残差为: 0.006178036008577692
计算收敛!

你可能感兴趣的:(python,numpy,matplotlib,算法)