Python進行有限元編程-平面應力問題(三節點三角形單元)

參考書籍是:《有限元方法基礎教程》(國際單位制)(第五版)

章節爲:第6章 建立平面應力和平面應變剛度方程

重要的事情繼續強調(有限元的基本計算流程):

Step 1: 選擇單元類型。

Step 2: 選擇位移函數。

Step 3: 定義應變/位移和 應力/應變關係。

Step 4: 推導單元剛度矩陣和方程。

Step 5: 組合單元剛度方程得出總體方程並引進邊界條件。

Step 6: 求解未知自由度。

Step 7:求解單元應變和應力。

Step 8: 解釋結果。

 

==> 關於三節點三角形單元的剛度矩陣的推導過程,詳見《有限元方法基礎教程》第6章 建立平面應力和平面應變剛度方程

==> 本次主要計算的問題見上圖。

==> 首先創建一個單元類。

==> 關於python中的構造函數(__init__方法)(因爲之前學習java程序,java程序有一個構造函數的說法)傳入的參數包括:三節點的座標,和楊氏模量,泊松比,以及單元的厚度。(單元的面積是根據節點的座標計算出來的)

import numpy as np

class T3(object):
    # 接下來首先創建類的構造函數 __init__
    # 對傳入的參數進行說明,需要傳入單元節點的座標數據 coordinates
    # 傳入材料的楊氏模量E; 材料的泊松比 v
    # 單元的厚度 t. 
    
    def __init__(self, coors, E, v, t):
        self.coors = coors
        self.E = E
        self.v = v
        self.t = t
        self.B = None
        self.D = None
        self.A = None

 

在初始化中,我們給當前單元增加了B矩陣,D矩陣,A(單元面積)作爲當前單元類的屬性(attribute)。

==> 首先計算出對應的B矩陣,B矩陣的推導公式見《有限元方法基礎教程》。(B矩陣是由N矩陣求偏導得來的)。

 def Bmat(self):
        # coors中的數據排列規則是 x_i, x_j, x_m, y_i, y_j, y_m
        x_i, x_j, x_m, y_i, y_j, y_m = self.coors
        # 首先計算出當前對應的行列式
        A2 = x_i * (y_j - y_m) + x_j*(y_m - y_i) + x_m*(y_i - y_j)
        # 然後計算生成對應的a_i, a_j, a_m
        a_i = x_j * y_m - y_j * x_m
        a_j = y_i * x_m - x_i * y_m
        a_m = x_i * y_j - y_i * x_j
        
        # 計算生成對應的beta
        b_i = y_j - y_m
        b_j = y_m - y_i
        b_m = y_i - y_j
        
        # 計算生成對應的r_i, r_j, r_m
        r_i = x_m - x_j
        r_j = x_i - x_m
        r_m = x_j - x_i
        
        # 然後將上述的所有的數據組合成B矩陣
        B = np.zeros((3, 6), dtype=np.float32)
        B[0][0] = b_i
        B[0][2] = b_j
        B[0][4] = b_m
        
        # 然後添加r數據
        B[1][1] = r_i
        B[1][3] = r_j
        B[1][5] = r_m
        # 然後下面添加對應的b和r數據
        B[2][0] = r_i
        B[2][1] = b_i
        B[2][2] = r_j
        B[2][3] = b_j
        B[2][4] = r_m
        B[2][5] = b_m
        return A2/2, B/A2

 

此處不僅計算出了B矩陣,還有當前單元的面積。這在單元剛度矩陣的公式中仍有應用。

==> 接下來是計算出對應的D矩陣,D矩陣是應力,應變關係的矩陣,本文主要是針對平面應力問題(注意區分平面應力問題和平面應變問題,兩者最主要的區別,可以按照如下的規則:在3D問題中的,當有一個方向上的尺寸遠小於另外兩個方向上的尺寸時,可將該問題簡化爲平面應力問題;當有一個方向上的尺寸遠大於另外兩個方向上的尺寸時,可將該問題簡化爲平面應變問題)

  # 接下來創建一個函數,來生成對應的D矩陣
    def Dmat(self):
        # 對於三角形三節點的,生成的D矩陣是3*3
        D = np.array([[1, self.v, 0], 
                      [self.v, 1, 0], 
                      [0, 0, (1-self.v)/2]])
        return D * self.E / (1 - self.v**2)

 

==> 對應於三節點三角形單元,其對應的單元剛度矩陣的表達式可以寫爲如下形式:

【k】= 【B】^T * 【D】 * 【B】 *  t * A;

==>這裏我們需要計算B矩陣的轉置矩陣,可以調用numpy中對於矩陣的轉置操作; 也可以自己添加轉置操作。

    def transpose(self, target:(list, np.ndarray)):
        # 首先把target包裝成np.ndarray
        if isinstance(target, list):
            target = np.array(target)
        # 然後創建一個新的數據內存
        Tmat = np.zeros((target.shape[1], target.shape[0]), dtype=np.float32)
        # 然後給Tmat進行遍歷賦值
        for row in range(target.shape[0]):
            for col in range(target.shape[1]):
                Tmat[col][row] = target[row][col]
        return Tmat

 

接下來創建一個生成單元剛度矩陣的函數。

  def stiffness_Matrix(self):
        # 這裏我麼首先需要獲取B矩陣
        if self.B == None or self.A == None:
            A, B = self.Bmat()
            self.A = A
            self.B = B
        # 接下來獲取對應的轉置矩陣B_T
        B_T = self.transpose(self.B)
        # 然後獲取D矩陣
        if self.D == None:
            D = self.Dmat()
            self.D = D
        # 首先進行B_T矩陣與D矩陣的相乘
        # 創建一個內存空間
        Mat_1 = np.zeros((B_T.shape[0], self.D.shape[1]), dtype=np.float32)
        # 創建一個臨時求和變量
        sum_value = 0
        # 然後接下來便是來計算出對應的數值
        for row in range(B_T.shape[0]):
            for col in range(self.D.shape[1]):
                sum_value = 0
                for n in range(B_T.shape[1]):
                    sum_value += B_T[row][n] * self.D[n][col]
                else:
                    # 迭代結束後,當前位置的數據便計算完成了
                    Mat_1[row][col] = sum_value
        # 循環結束後,當前的矩陣相乘便計算完畢了
        # 接下來繼續處理Mat_1矩陣和B矩陣相乘的計算過程
        # 開闢內存空間
        Mat_2 = np.zeros((Mat_1.shape[0], self.B.shape[1]), dtype=np.float32)
        for row in range(Mat_1.shape[0]):
            for col in range(self.B.shape[1]):
                sum_value = 0
                for n in range(Mat_1.shape[1]):
                    sum_value += Mat_1[row][n] * self.B[n][col]
                else:
                    Mat_2[row][col] = sum_value
        
        # 矩陣乘積結束之後,需要做的是去乘t
        return Mat_2 * self.t * A

 

==> 將上述問題的座標信息輸入到程序中去,得到對應的單元剛度矩陣。

對比書上的課後答案如下:

 

扶貧方式如下:

發佈了12 篇原創文章 · 獲贊 6 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章