zoukankan      html  css  js  c++  java
  • plot3d网格读取写入与可视化


    说明

    plot3d格式是NASA制定并大量使用的CFD网格文件格式,在CFD编程过程中经常涉及到。本文利用Python语言编写一个读取plot3d文件,写入plot3d文件的通用类,并利用vtk完成网格的显示。

    对于程序的说明

    1. 使用说明

    在主函数中,写入如下代码:

    # 新建对象
    mesh = Mesh()
    
    # 读文件
    fname = 'demo.fmt'
    mesh.read(fname)
    
    fname1 = "1111.dat"
    mesh.write(fname1)
    
    1. 程序思路

    定义Mesh类,包含有:

    属性:
    1. 网格维度: DIM = 3
    2. 网格块数目: int BlockNum
    3. 网格块坐标数目:np.array([]) Block_list
    4. 网格块列表 list(Block)
    方法:
    1. setBlockNum: 设置网格块数目
    2. setBlockList: 设置网格块数目
    3. MeshInit: 创建mesh对象,给BlockNum和Block_list赋值
    4. setBlock: 设置每一个块的坐标和IBLANK

    每个Block具有:
    1. id,jd,kd: 三个方向上坐标数目
    2. X,Y,Z: 三个方向的坐标分量(一维列阵)
    3. IBlank:当前块的IBlank值

    源码

    # !/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    import math
    import numpy as np
    
    
    class Block():
        """
        描述Plot3d文件中的一个Block
        """
    
        def __init__(self, ID, JD, KD):
            self.id = ID
            self.jd = JD
            self.kd = KD
            self.X = np.zeros(self.id)
            self.Y = np.zeros(self.jd)
            self.Z = np.zeros(self.kd)
            self.IBlank = np.zeros(self.id * self.jd * self.kd)
    
        def setX(self, x_list):
            self.X = x_list
    
        def setY(self, y_list):
            self.Y = y_list
    
        def setZ(self, z_list):
            self.Z = z_list
    
        def setBlank(self, blank_list):
            self.IBlank = blank_list
    
        def setXYZ(self, x_list, y_list, z_list):
            self.X = x_list
            self.Y = y_list
            self.Z = z_list
    
    
    class Mesh():
        """
        描述一个plot3d网格文件
        """
    
        def __init__(self):
            self.DIM = 3
            self.blockNum = 1
            self.block_list = []
            self.BLOCK = []
    
        def setBlockNum(self, block_num):
            self.blockNum = block_num
    
        def setBlockList(self, block_list):
            self.block_list = block_list
    
        def MeshInit(self, block_num, block_list):
            self.setBlockNum(block_num)
            self.setBlockList(block_list)
            for i in range(self.blockNum):
                bl = Block(*self.block_list[3 * i:3 * (i + 1)])
                self.BLOCK.append(bl)
    
        def setBlock(self, i, coordinates_list, iblank_list):
            self.BLOCK[i - 1].setXYZ(*coordinates_list)
            self.BLOCK[i - 1].setBlank(iblank_list)
    
        def check(self):
            if len(self.block_list) != self.blockNum * self.DIM:
                print("The Block Num and the Block list is not consistent.")
            for i in range(self.blockNum):
                block = self.BLOCK[i]
                ID = block.id
                JD = block.jd
                KD = block.kd
                pointNum = ID * JD * KD
                flag = len(block.X) == pointNum and len(block.Y) == pointNum
                flag = flag and len(block.Z) == pointNum
                if not flag:
                    print("The point number is not consistent.")
    
        def write(self, fname):
            self.check()
            data = ''
            try:
                with open(fname, 'w') as f:
                    # 写入Block数目
                    line = '	{:>8d}
    '
                    data += line.format(self.blockNum)
                    # f.write(line.format(self.blockNum))
                    line = '	'
                    for i in range(len(self.block_list)):
                        line = line + '{' + str(i) + ':>8d}	'
                        if (i + 1) % 6 == 0:
                            line += '
    	'
                    line += '
    '
                    data += line.format(*self.block_list)
                    # f.write(line.format(*self.block_list))
                    for block in self.BLOCK:
                        # 循环写入X,Y,Z坐标
                        for xi in [block.X, block.Y, block.Z]:
                            line = '  '
                            for i in range(len(xi)):
                                line = line + '{' + str(i) + ': 7E}    '
                                if (i + 1) % 5 == 0:
                                    line += '
      '
                            line += '
    '
                            data += line.format(*xi)
                            # f.write(line.format(*xi))
                        # 写入iBlank
                        line = '	'
                        for i in range(len(block.IBlank)):
                            line = line + '{' + str(i) + ': 9d}' + '	'
                            if (i + 1) % 6 == 0:
                                line += '
    	'
                        line += '
    '
                        data += line.format(*block.IBlank)
                        # f.write(line.format(*block.IBlank))
                    f.write(data)
            except (BaseException):
                print("写出文件时发生错误!请检查您的输出数据结构。")
                exit(1)
    
        def read(self, fname):
            try:
                with open(fname, 'r') as f:
                    # 读取块号
                    line = f.readline().strip()
                    self.blockNum = int(line)
                    # 读取block_list
                    num = math.ceil((self.DIM * self.blockNum) / 6)
                    line = ''
                    for i in range(num):
                        line += f.readline()
                    line = line.split()
                    block_list = np.array([int(i) for i in line])
                    self.block_list = block_list
                    # 初始化Mesh
                    self.MeshInit(self.blockNum, self.block_list)
    
                    # 读取每个块信息
                    for ibl in range(self.blockNum):
                        bl = self.BLOCK[ibl]
                        # 获取block_list信息
                        bl.id, bl.jd, bl.kd = self.block_list[self.DIM *
                                                              ibl:self.DIM *
                                                              (ibl + 1)]
                        point_num = bl.id * bl.jd * bl.kd
                        num = math.ceil(point_num / 5)
                        # 获得x
                        line = ''
                        for i in range(num):
                            line += f.readline()
                        line = line.split()
                        x_list = np.array([float(im) for im in line])
                        # 获得y
                        line = ''
                        for i in range(num):
                            line += f.readline()
                        line = line.split()
                        y_list = np.array([float(im) for im in line])
                        # 获得z
                        line = ''
                        for i in range(num):
                            line += f.readline()
                        line = line.split()
                        z_list = np.array([float(im) for im in line])
                        # 获得iblank
                        line = ''
                        num = math.ceil(bl.id * bl.jd * bl.kd / 6)
                        for i in range(num):
                            line += f.readline()
                        line = line.split()
                        iblank_list = np.array([int(im) for im in line])
                        self.setBlock(ibl, [x_list, y_list, z_list], iblank_list)
            except (BaseException):
                pass
            self.check()
    
        def visual(self):
            """
            显示网格信息
            """
            pass
    
    
    if __name__ == '__main__':
        mesh = Mesh()
    
        # 读文件
        fname = 'demo.fmt'
        mesh.read(fname)
    
        fname1 = "1111.dat"
        mesh.write(fname1)
    
    
  • 相关阅读:
    深入理解委托、匿名方法和 Lambda 表达式
    常见SQL问题
    LeetCode题解——四数之和
    把中台说清楚
    程序员们的三高:高并发、高性能、高可用
    论文查重是怎么查的
    LeetCode题解——最长回文子串
    六百字读懂 Git(转)
    SQL中ON和WHERE的区别
    链表排序之堆排序
  • 原文地址:https://www.cnblogs.com/baowee/p/11191814.html
Copyright © 2011-2022 走看看