用Python对Hypermesh四面体抽壳 您所在的位置:网站首页 hypermesh导入文件重叠 用Python对Hypermesh四面体抽壳

用Python对Hypermesh四面体抽壳

2023-10-09 11:08| 来源: 网络整理| 查看: 265

本人最近遇到一个问题,要对Hypermesh中的四面体抽壳,所以用Python做了一个四面体抽壳的工具,写博客记录一下。

首先在Hypermesh中导出K文件,接下来的所有操作都是基于K文件进行的,Hypermesh导出K文件如下图:

 Hypermesh导入K文件如下图:

第一步,逐行读取K文件,识别K文件中的单元类型。

        一般情况下K文件含有2种二维单元(shell):三角形和四边形;含有3种三维单元(solid):四面体,六面体,八面体。

from itertools import combinations import re from ToolBox import My_write,My_deletfile,My_recgnize,My_f_write,Find_max_ID def read_k_file(filename): i = 1 shell_num = 0 solid_num = 0 pp = "" with open(filename,"r") as F: while True: Line=F.readline() if Line: pp = pp + Line if "*ELEMENT_SHELL" in Line: shell_num=shell_num+1 elif "*ELEMENT_SOLID" in Line: solid_num=solid_num+1 else: break return pp,shell_num,solid_num #pp是K文件全部内容,shell_num是shell数量,solid_num是solid数量

 函数返回值为包含整个K文件的字符串,shell数量和solid数量,用于判断文件中书否含有待处理的四面体

第二步,分割K文件

        将K文件分割为几部分:

               文件头(head),文件尾(button),根据具体情况将具体单元信息分割为几部分(shell_3,shell_4;solid_4,solid_6,

solid_8),分别存入几个文件中,以待后用

def split_file(pp,shell_num,solid_num): My_deletfile("shell_3.k") My_deletfile("shell_4.k") My_deletfile("shell_temp.k") My_deletfile("solid_4.k") My_deletfile("solid_6.k") My_deletfile("solid_8.k") My_deletfile("solid_temp1.k") My_deletfile("solid_temp2.k") My_deletfile("solid_temp3.k") #首先清除所有中间文件 if shell_num: head = re.compile(r'(.*?)\n\*ELEMENT_SHELL.*?END', re.S) My_write(head,pp,"head.k") #提取文件头 if shell_num==2: #如果shell_num=2,说明K文件中有全部两种shell单元,三角形在前,四边形在后,依次输出即可 shell_3 = re.compile(r'\*ELEMENT_SHELL\n(.*?)\n\*ELEMENT_SHELL.*?END', re.S) My_write(shell_3,pp,"shell_3.k") print("三角形输出完毕") shell_4 = re.compile(r'\*ELEMENT_SHELL.*?\*ELEMENT_SHELL\n(.*?)\n\*.*?END', re.S) My_write(shell_4,pp,"shell_4.k") print("四边形输出完毕") elif shell_num==1: #如果shell_num=1,说明只有一种shell单元,可能是三角形,也可能是四面体,这时需要先写入到临时文件中进一步判断 shell_temp = re.compile(r'\*ELEMENT_SHELL\n(.*?)\n\*.*?END', re.S) My_write(shell_temp, pp, "shell_temp.k") My_recgnize("shell_temp.k")#进一步判断单元类型 else: #shell_num=0,即没有面单元,如果有体单元,则头文件为*ELEMENT_SOILD之前的部分;如果也没有体单元,则输出警告 if solid_num: head = re.compile(r'(.*?)\n\*ELEMENT_SOLID.*?END', re.S) My_write(head, pp, "head.k") else: print("没有体单元,也没有面单元") if solid_num: if solid_num==3: #如果文件中含全部三种体单元,按四面体,六面体,八面体的顺序输出即可,否则需要先写入临时文件,进一步判断 solid_4=re.compile(r'\*ELEMENT_SOLID\n(.*?)\n\*ELEMENT_SOLID.*?\*ELEMENT_SOLID.*?\*.*?END',re.S) My_write(solid_4,pp,"solid_4.k") print("四面体输出完毕") solid_6 = re.compile(r'\*ELEMENT_SOLID\n.*?\n\*ELEMENT_SOLID\n(.*?)\n\*ELEMENT_SOLID.*?\*.*?END', re.S) My_write(solid_6, pp, "solid_6.k") print("六面体输出完毕") solid_8 = re.compile(r'\*ELEMENT_SOLID\n.*?\n\*ELEMENT_SOLID.*?\*ELEMENT_SOLID\n(.*?)\n\*.*?END', re.S) My_write(solid_8, pp, "solid_8.k") print("八面体输出完毕") button = re.compile(r'\*ELEMENT_SOLID.*?\*ELEMENT_SOLID.*?\*ELEMENT_SOLID.*?(\*.*?END)', re.S) My_write(button,pp,"button.k") elif solid_num==2: solid_temp1 = re.compile(r'\*ELEMENT_SOLID\n(.*?)\n\*ELEMENT_SOLID.*?\*.*?END', re.S) My_write(solid_temp1, pp, "solid_temp1.k") My_recgnize("solid_temp1.k") solid_temp2 = re.compile(r'\*ELEMENT_SOLID.*?\*ELEMENT_SOLID\n(.*?)\n\*.*?END', re.S) My_write(solid_temp2, pp, "solid_temp2.k") My_recgnize("solid_temp2.k") button = re.compile(r'\*ELEMENT_SOLID.*?\*ELEMENT_SOLID.*?(\*.*?END)', re.S) My_write(button, pp, "button.k") elif solid_num==1: solid_temp3 = re.compile(r'\*ELEMENT_SOLID\n(.*?)\n\*.*?END', re.S) My_write(solid_temp3, pp, "solid_temp3.k") My_recgnize("solid_temp3.k") button = re.compile(r'\*ELEMENT_SOLID.*?(\*.*?END)', re.S) My_write(button, pp, "button.k") else: print("没有体单元")

用到的函数:

#删除文件函数 def My_deletfile(filename): if os.path.exists(filename): # 删除文件,可使用以下两种方法。 os.remove(filename) # os.unlink(my_file) print("成功删除文件:%s" %filename) else: print('不存在文件:%s' % filename) #进一步判断单元类型 def My_recgnize(filename): with open(filename,"r",encoding="utf-8") as f: Line=f.readline() lline=Line.split() print(lline) content = f.read() if len(lline)==6: if lline[5]==lline[4]: with open("shell_3.k","w",encoding="utf-8")as F : F.write(content) print("三角形输出完毕") elif lline[4]!=lline[5]: with open("shell_4.k","w",encoding="utf-8")as F : F.write(content) print("四边形输出完毕") else: print("都不是") if len(lline)==10: if lline[8]==lline[6]==lline[7]: with open("solid_4.k", "w", encoding="utf-8")as F: F.write(content) print("四面体输出完毕") elif lline[7]==lline[6] and lline[8]!=lline[7]: with open("solid_6.k", "w", encoding="utf-8")as F: F.write(content) print("六面体输出完毕") else: with open("solid_8.k", "w", encoding="utf-8")as F: F.write(content) print("八面体输出完毕")

第三步,四面体抽壳和重新封装K文件

        首先选择文件保存目录,并将头文件先存入目标文件。

        如果原文件含三角形,则先写入,然后对四面体抽壳并将结果写入目标文件;如果没三角形,则直接将四面体抽壳的结果写入。

        四面体抽壳:

                逐行读取第二步中得到的solid_4文件,数据格式如下:

                3177856    2009 3093371 3080613 3093375 3080578 3080578 3080578 3080578 3080578

                共10列数据,每列8位,其中第一列为单元ID,第二行为componentID,3~10列为组成单元的8个NodeID。我们可以看到四面体的第5~8个NodeID相同,因此取1~4个NodeID进行排列组合。

          之后将其他单元和文件尾按顺序写入即可

重组主函数:

def Reorder(filename): My_deletfile(filename) with open(filename,"a",encoding="utf-8") as f: Write_orign("head.k",f) Write_orign("shell_3.k",f) Write_orign("shell_4.k", f) Write_orign("solid_4.k", f) Write_orign("solid_6.k", f) Write_orign("solid_8.k", f) Write_orign("button.k", f)

写入文件函数:

def Write_orign(filename,f): try: with open(filename,"r",encoding="utf-8") as Orign: if filename == "shell_3.k": f.write("*ELEMENT_SHELL"+"\n") solid2shell(f) elif filename == "shell_4.k": f.write("*ELEMENT_SHELL" + "\n") elif filename == "solid_4.k" or filename == "solid_6.k" or filename == "solid_8.k": f.write("*ELEMENT_SOLID"+"\n") f.write(Orign.read()+"\n") except: if filename=="shell_3.k": f.write("*ELEMENT_SHELL"+"\n") solid2shell(f) print("文件%s" %filename+"不存在")

 四面体抽壳函数:

def solid2shell(f): MAX_ID=max(Find_max_ID("shell_3.k",0),Find_max_ID("shell_4.k",0),Find_max_ID("solid_4.k",0), Find_max_ID("solid_6.k",0),Find_max_ID("solid_8.k",0)) MAX_comp_ID = max(Find_max_ID("shell_3.k", 1), Find_max_ID("shell_4.k", 1), Find_max_ID("solid_4.k", 1), Find_max_ID("solid_6.k", 1), Find_max_ID("solid_8.k", 1)) with open("solid_4.k",'r') as solid: k = 1 while True: line = solid.readline() if line: line1=line.split() sort=list(combinations(line1[2:6],3)) for i in range(len(sort)): My_f_write(MAX_ID+k,f) k = k + 1 My_f_write(MAX_comp_ID+1,f) for j in range(len(sort[0])): My_f_write(int(sort[i][j]),f) My_f_write(sort[i][2]+"\n",f) else: break

寻找最大partID和conponentID函数:

def Find_max_ID(filename,num): try: with open(filename,"r",encoding="utf-8") as f: ID=[0,0] while True: line=f.readline() if line: Line=line.split() try: ID[0]=int(Line[num]) if ID[0]>ID[1]: ID[1]=ID[0] except: continue else: break return ID[1] except: return 0

 按8位格式将数据写入文件函数:

def My_f_write(A,f): if int(A)>= 0 and int(A)< 10: f.write(" " * 7 + str(A)) if int(A) >= 10 and int(A) < 100: f.write(" " * 6 + str(A)) if int(A) >= 100 and int(A) < 1000: f.write(" " * 5 + str(A)) if int(A) >= 1000 and int(A) < 10000: f.write(" " * 4 + str(A)) if int(A) >= 10000 and int(A) < 100000: f.write(" " * 3 + str(A)) if int(A) >= 100000 and int(A) < 1000000: f.write(" " * 2 + str(A)) if int(A) >= 1000000 and int(A) < 10000000: f.write(" " * 1 + str(A)) if int(A) >= 10000000 and int(A) < 100000000: f.write(str(A))

第五步,制作UI

为了给程序加上UI,我使用了PyQt5库。同时还对前文中的一些函数做了更改,但基本的原理没有改变,更改的目的只是让UI更人性化。UI程序如下:

import sys from PyQt5.QtWidgets import QMainWindow, QPushButton, QApplication,QFileDialog,QMessageBox,QLineEdit,QLabel from Read_K_File import read_k_file,split_file,Reorder from PyQt5.QtGui import QIcon,QPixmap,QGuiApplication from random import randint from time import clock,sleep from ToolBox import My_deletfile class Example(QMainWindow): def __init__(self): super().__init__() self.pp = "" self.shell_num = 0 self.solid_num = 0 self.initUI() def initUI(self): self.inputfile_name = QLineEdit(self) self.inputfile_name.move(220, 438) self.inputfile_name.resize(760, 40) self.outputfile_name = QLineEdit(self) self.outputfile_name.move(220, 498) self.outputfile_name.resize(760, 40) #lable_2=QLabel() #lable_2.setGeometry(100,500,100,100) #lable_2.setPixmap(QPixmap("D:\document\Python\GUIdesign\Boom.jpg")) self.lb1 = QLabel(self) self.lb1.setGeometry(20, 20, 225, 400) self.lb2 = QLabel(self) self.lb2.setGeometry(20+225+20, 20, 225, 400) self.lb3 = QLabel(self) self.lb3.setGeometry(20+225+20+225+20, 20, 225, 400) self.lb4 = QLabel(self) self.lb4.setGeometry(20+225+20+225+20+225+20, 20, 225, 400) self.create_fignum() btn1 = QPushButton("选择待处理K文件", self) btn1.move(20, 438) btn1.resize(180,40) btn2 = QPushButton("选择K文件保存目录", self) btn2.move(20, 498) btn2.resize(180,40) btn3 = QPushButton("第一步:读取K文件", self) btn3.move(20, 558) btn3.resize(300,40) btn4 = QPushButton("第二步:分割K文件", self) btn4.move(350, 558) btn4.resize(300, 40) btn5=QPushButton("第三步:四面体抽壳&&&重组K文件",self) btn5.move(680,558) btn5.resize(300, 40) btn1.clicked.connect(self.buttonClicked) btn2.clicked.connect(self.buttonClicked) btn3.clicked.connect(self.Read_K_file) btn4.clicked.connect(self.Split_K_file) btn5.clicked.connect(self.Reorder) self.setGeometry(300, 300, 1000,618 ) self.setWindowTitle('四面体抽壳小程序') self.setWindowIcon(QIcon("img\Boom.jpg")) self.show() self.setFixedSize(self.width(), self.height()) self.gui = QGuiApplication.processEvents def create_fignum(self): fig_num = [randint(1, 28)] while True: if len(fig_num)


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有