基于Python的三角网格划分

一、矩形网格单元的生成

矩形网格单元

如上图所示,黑色数字表示的是节点,蓝色数字表示的是element的位置,每个节点对应一个黑色数字,每一个element有四个节点与之对应,基于Python的编程,我们可以得到节点的位置列表,储存着所有节点的位置坐标,且列表的索引即为节点的索引,同时对遍历所有的element可以得到element的节点索引列表,列表中存储着每个element对应的四个节点的索引,element列表的索引即为element的编号。

二、三角网格单元的生成

在有限元算法中,多是基于三角网格的算法,我们可以从矩形网格中得到标准的三角网格单元,对于矩形网格中的每一个矩形单元可以将其按对角线进行剖分成两个三角形单元,并重新进行编号。
进过剖分之后,element的数量变成原来的两倍,每个element对应三个节点。据此我们得到了下面的三角网格单元“

三角网格单元
matplotlib中提供了基于非规则三角网格的绘图工具,我们生成的三角网格也是可以使用的,使用其中的tri库我们可以绘制出以下结果:
matplotlib.tri 绘制

三、参考代码

# -*- coding: utf-8 -*-
'''
该程序用于创建二维有限元标准三角网格程序,其中利用了四角网格的剖分
来建立三角网格,计算得到代表网格node坐标列表,列表的索引为node 的
索引,得到element节点索引列表。
@作者:fm
'''
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.tri as mtri

def creat_mesh(x, y, nx, ny, e_type):
    '''
    x:x方向上的距离
    x:y方向上的距离
    nx:x方向上的element的数量
    ny:y方向上的element的数量
    e_type:SQ表示是矩形单元,TR表示三角单元

    '''
    # 矩形单元的四角坐标
    q = np.array([[0., 0.], [x, 0.], [0, y], [x, y]])
    # node的数量
    numN = (nx+1)*(ny+1)
    # element的数量
    numE = nx*ny
    # 矩形element的角
    NofE = 4
    # 二维坐标
    D = 2
    # nodes 坐标
    NC = np.zeros([numN, D])
    # dx,dy的计算
    dx = q[1, 0]/nx
    dy = q[2, 1]/ny
    # nodes 坐标计算
    n = 0
    for i in range(1, ny+2):
        for j in range(1, nx+2):
            NC[n, 0] = q[0, 0] + (j-1)*dx
            NC[n, 1] = q[0, 1] + (i-1)*dy

            n += 1
    # element 索引,一个element由四个角的节点进行索引
    EI = np.zeros([numE, NofE])

    for i in range(1, ny+1):
        for j in range(1, nx+1):
            # 从底层开始类推
            if j == 1:
                EI[(i-1)*nx+j-1, 0] = (i-1)*(nx+1) + 1
                EI[(i-1)*nx+j-1, 1] = EI[(i-1)*nx+j-1, 0] + 1
                EI[(i-1)*nx+j-1, 3] = EI[(i-1)*nx+j-1, 0] + (nx+1)
                EI[(i-1)*nx+j-1, 2] = EI[(i-1)*nx+j-1, 3] + 1
            else:
                EI[(i-1)*nx+j-1, 0] = EI[(i-1)*nx+j-2, 1]
                EI[(i-1)*nx+j-1, 3] = EI[(i-1)*nx+j-2, 2]
                EI[(i-1)*nx+j-1, 1] = EI[(i-1)*nx+j-1, 0] + 1
                EI[(i-1)*nx+j-1, 2] = EI[(i-1)*nx+j-1, 3] + 1
    # 至此完成了矩形单元的划分工作
    # 三角形单元需要将每一个矩形单元进行拆分,即一分二成两个三角形
    if e_type == 'TR':
        # 三角形的三个角
        NofE_new = 3
        # 单元数量
        numE_new = numE * 2
        # 新的三角单元索引
        EI_new = np.zeros([numE_new, NofE_new])

        # 对矩形单元进行逐个剖分
        for i in range(1, numE+1):
            EI_new[2*(i-1), 0] = EI[i-1, 0]
            EI_new[2*(i-1), 1] = EI[i-1, 1]
            EI_new[2*(i-1), 2] = EI[i-1, 2]

            EI_new[2*(i-1)+1, 0] = EI[i-1, 0]
            EI_new[2*(i-1)+1, 1] = EI[i-1, 2]
            EI_new[2*(i-1)+1, 2] = EI[i-1, 3]

        EI = EI_new
    EI = EI.astype(int)
    return NC, EI


x, y = 1, 1
nx = 5
ny = 4
element_type = 'TR'
NC, EI = creat_mesh(x, y, nx, ny, element_type)
numN = np.size(NC, 0)
numE = np.size(EI, 0)
plt.figure(1)
count = 1
# plot nodes num
for i in range(numN):
    plt.annotate(count, xy=(NC[i, 0], NC[i, 1]))
    count += 1

if element_type == 'SQ':
    count2 = 1
    for i in range(numE):
        # 计算中点位置
        plt.annotate(count2, xy=((NC[EI[i, 0]-1, 0]+NC[EI[i, 1]-1, 0])/2,
                                 (NC[EI[i, 0]-1, 1]+NC[EI[i, 3]-1, 1])/2),
                     c='blue')
        count2 += 1
        # plot lines
        x0, y0 = NC[EI[i, 0]-1, 0], NC[EI[i, 0]-1, 1]
        x1, y1 = NC[EI[i, 1]-1, 0], NC[EI[i, 1]-1, 1]
        x2, y2 = NC[EI[i, 2]-1, 0], NC[EI[i, 2]-1, 1]
        x3, y3 = NC[EI[i, 3]-1, 0], NC[EI[i, 3]-1, 1]
        plt.plot([x0, x1], [y0, y1], c='red', linewidth=3)
        plt.plot([x0, x3], [y0, y3], c='red', linewidth=3)
        plt.plot([x1, x2], [y1, y2], c='red', linewidth=3)
        plt.plot([x2, x3], [y2, y3], c='red', linewidth=3)
        
if element_type == 'TR':
    count2=1
    for i in range(numE):
        # 计算中点位置
        plt.annotate(count2, xy=((NC[EI[i, 0]-1, 0]+NC[EI[i, 1]-1, 0]+NC[EI[i, 2]-1, 0])/3,
                                 (NC[EI[i, 0]-1, 1]+NC[EI[i, 1]-1, 1]+NC[EI[i, 2]-1, 1])/3),
                     c='blue')
        count2 += 1
        x0, y0 = NC[EI[i, 0]-1, 0], NC[EI[i, 0]-1, 1]
        x1, y1 = NC[EI[i, 1]-1, 0], NC[EI[i, 1]-1, 1]
        x2, y2 = NC[EI[i, 2]-1, 0], NC[EI[i, 2]-1, 1]
        plt.plot([x0, x1], [y0, y1], c='red', linewidth=3)
        plt.plot([x1, x2], [y1, y2], c='red', linewidth=3)
        plt.plot([x0, x2], [y0, y2], c='red', linewidth=3)
# plt.xlim(0, x)
# plt.ylim(0, y)
plt.axis("equal")
plt.show()

plt.figure(2)
x=np.squeeze(NC[:,0])
y=np.squeeze(NC[:,1])
tri=EI-1
triang = mtri.Triangulation(x,y,tri)
plt.tricontourf(triang,np.zeros_like(x))
plt.triplot(triang,'go-')
plt.show()

### 微分方程数值求解中的三角形网格生成方法 在微分方程的数值求解过程中,尤其是对于偏微分方程(PDEs),采用有限元法(FEM)或边界元法(BEM)时,通常需要将连续区域离散化成多个简单形状的小单元来近似原始问题。这些小单元可以是矩形、四边形或多边形,在二维空间中最常用的是三角形单元。 #### 一、Delaunay Triangulation算法简介 为了创建高质量的三角形网格,一种广泛使用的自动网格生成功能就是基于Delaunay准则构建三角剖分图。该算法能够确保任何四个顶点组成的凸包内部不存在其他节点,并且最大化最小角以减少狭长三角形的数量。这有助于提高后续计算精度并降低条件数[^1]。 ```python import matplotlib.pyplot as plt from scipy.spatial import Delaunay points = [[0, 0], [2, 4], [3, 1], [5, 2]] tri = Delaunay(points) plt.triplot([p[0] for p in points],[p[1] for p in points], tri.simplices.copy()) plt.plot([p[0] for p in points],[p[1] for p in points],'o') plt.show() ``` 此Python代码片段展示了如何利用SciPy库实现简单的Delaunay三角剖分可视化。 #### 二、自适应细化策略 当处理复杂几何结构或者局部特征尺度差异较大时,全局均匀分布的网格可能无法满足需求。此时可以通过引入自适应技术动态调整特定区域内网格密度。例如,在应力集中区增加更多细分层次;而在远离载荷作用位置的地方保持较稀疏布局即可[^2]。 #### 三、质量评估指标 一个好的三角网应该具备良好的形态特性,即避免过尖锐的角度以及过度拉伸的情况发生。具体来说: - **Aspect Ratio**: 定义为最长边与最短高之比; - **Skewness**: 表征偏离理想直角的程度; - **Orthogonality Error**: 测量相邻两面之间交线方向同其所在平面正交程度之间的偏差。 通过监控以上参数的变化趋势可以帮助判断所生成网格的质量优劣,并据此采取相应改进措施[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值