python - 使用 matplotlib 绘制有限元网格的最有效方法?

标签 python numpy matplotlib numeric

我的问题相当简单,但对于那些需要更多背景信息的人,请参阅 wikipedia page on finite element methods .

我正在寻找使用 matplotlib 绘制网格的最有效方法,给出以下信息、每个节点的坐标、属于每个元素的节点以及每个节点具有的值。下面我有一些示例数据和图像,显示了网格的外观

nodeinfo=[[0.000,0.000],[1.000,0.000],[2.000,0.500],[0.000,1.000],
[1.000,1.000],[1.750,1.300],[1.000,1.700]]
elementInfo=[[1,2,5],[5,4,1],[2,3,6],[6,5,2],[4,5,7],[5,6,7]]
nodevalues=[1,2,1,2,7,4,5]

enter image description here

nodeinfo 是每个节点的坐标(例如节点 7 的坐标为 (1,1.7)),elementInfo 给出每个元素由哪些节点组成(例如元素 3 具有节点 2,3,6),nodevalues 给出的值每个节点(例如节点 5 的值为 7)。

Using this info how can I plot meshes with matplotlib with a colour gradient showing the different values of the nodes(if possible it would be great if there was a colour gradient between nodes as each element is linear).

注意 如果您想使用它,请创建一些将信息组织到节点对象中的代码。

class node:
    # Initializer / Instance Attributes
    def __init__(self, number, xCord, yCord):
        self.number=number
        self.value=1
        self.isOnBoundary=False
        self.xCord=xCord
        self.yCord=yCord
        self.boundaryType=None
        self.element=[]

    #makes all class variables callable
    def __call__(self):
        return self

    def checkIfOnBoundary(self,boundarylist):
        # Checks if the node is on the boundary when it is invoked
        # If the node is not on the boundary then it is set to false

        if self.number in boundarylist:
            self.isOnBoundary=True
            self.boundaryType=boundarylist[self.number][0]
            if self.boundaryType == "Dirchlet":
                self.value=boundarylist[self.number][1]
        else:
            self.isOnBoundary=False

    def setElement(self,elementInfo):
        #given a list in the form [element1,element2,...,elementn]
        #where element1 is a list that contains all the nodes that are on that element
        for element in elementInfo:
            if self.number in element:
                self.element.append(elementInfo.index(element)+1)


    def setValue(self,value):
        # changes the value of the node
        self.value=value

    def description(self):
        return "Node Number: {}, Node Value: {}, Element Node Belongs to: {}, Is Node On the Boundary: {}".format(self.number, self.value, self.element, self.isOnBoundary)

nodeinfo=[[0.000,0.000],[1.000,0.000],[2.000,0.500],[0.000,1.000],
[1.000,1.000],[1.750,1.300],[1.000,1.700]]
elementInfo=[[1,2,5],[5,4,1],[2,3,6],[6,5,2],[4,5,7],[5,6,7]]
nodevalues=[1,2,1,2,7,4,5]

#create list of node objects which we will call on often
nodes=[]
for i in range(len(nodeinfo)):
    print(i)
    nodes.append(node(i+1,nodeinfo[i][0],nodeinfo[i][1]))
    nodes[i].setElement(elementInfo)

#print information related to each object
for phi in nodes:
    print(vars(phi))

最佳答案

首先,使用matplotlib.tri.Triangulation(x, y,triangles)创建一个非结构化三角网格,其中:

  • x 是一个一维列表,包含每个节点的 x 坐标;
  • y 是一个一维列表,包含每个节点的 y 坐标;
  • triangles 是一个“2D 列表”,包含每个三角形的节点(0 基于索引);

其次,使用matplotlib.pyplot.triplot(triangulation, linespec)仅绘制网格(仅线),其中:

  • triangulation 是由 matplotlib.tri.Triangulation(x, y,triangles) 创建的实例;
  • linespec 是线路规范;

第三,使用matplotlib.pyplot.tricontourf(triangulation, scalars)绘制标量场轮廓,其中:

  • triangulation 是由 matplotlib.tri.Triangulation(x, y,triangles) 创建的实例;
  • scalars 包含节点标量数据的一维列表;

最后,使用matplotlib.pyplot.colorbar()matplotlib.pyplot.show()

完整代码:

import matplotlib.pyplot as plt
import matplotlib.tri as tri

nodes_x = [0.000, 1.000, 2.000, 0.000, 1.000, 1.750, 1.000]
nodes_y = [0.000, 0.000, 0.500, 1.000, 1.000, 1.300, 1.700]
scalars = [1.000, 2.000, 1.000, 2.000, 7.000, 4.000, 5.000]
elements = [
    [0, 1, 4],
    [4, 3, 0],
    [1, 2, 5],
    [5, 4, 1],
    [3, 4, 6],
    [4, 5, 6]
    ]

triangulation = tri.Triangulation(nodes_x, nodes_y, elements)
plt.triplot(triangulation, '-k')
plt.tricontourf(triangulation, scalars)
plt.colorbar()
plt.show()

输出:

enter image description here

如果您想可视化其他类型的二维元素(四边形或高阶元素),则必须首先将它们“拆分”为三角形。但是,如果您想可视化 3D 元素,或者如果您想让您的生活更轻松,并且您的代码对于大型网格更高效/更快,您必须放弃 matplotlib 并使用 VTK 之类的东西。

编辑

检查我对以下问题的回答,以绘制包含四边形的 FEM 网格:

How can I plot 2d FEM results using matplotlib?

关于python - 使用 matplotlib 绘制有限元网格的最有效方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55750032/

相关文章:

python - 当数据不是周期性的时,如何绘制基于堆叠的条形图

python迭代xml避免命名空间

python - 无法使用 AWS SAM 构建 python 应用程序

python - 计算 pandas 中的高低

python - "Merging"具有共同维度的 numpy 数组

python - 使用plot_acf时不显示置信区间

python - 使用 Matplotlib 绘制散点图矩阵的刻度属性

python - 我如何告诉 'setup.py' 包含我的根目录中的文件以用于构建的发行版?

Python/Regex - 如何使用正则表达式从文件名中提取日期?

python - 值与一组值的矢量化比较