用TetGen对圆柱组合体进行网格剖分
TetGen 是一款网格剖分的软件,可以生成高质量的非结构四面体网格。他可以编译生成可执行文件后作为一个独立的软件通过命令行调用,或者嵌入其他程序之中。它支持的输入文件格式有很多,如 .poly ,.smesh ,.node 文件,我习惯采用的是 .poly 文件作为输入文件。tetgen使用手册里只给出了立方体.poly文件的示例,如果想生成一个圆柱体,或者多个圆柱组合体的 .poly 文件就没有参考的例子了,只好自己动手丰衣足食。
圆柱体构造的主要思想在于用多边形逼近圆,所以文中的python代码也适合用于生成多面体网格。
生成一个单独的圆柱体:
#generate only one cylinder import os import sys import time import math def main(argv): cputime_start = time.clock() cylinder_r = float(argv[1]) #the radius of the cylinder cylinder_h = float(argv[2]) #the height of the cylinder
print 'The radius of the cylinder is %0.3f' % cylinder_r print 'The height of the cylinder is %0.3f' % cylinder_h boxname = 'cylinder' + '-' + str(cylinder_r) + '-' + str(cylinder_h) + '.poly' boxf = open(boxname,'w') theta = math.pi/64 #use a polygon to approximat a circle nodenum = 256 nodenum_half = 128 #save the information of nodes node = [[0 for col in range(4)] for row in range(nodenum)] for i in range(0,nodenum): node[i] = [i+1,0,0,0] for i in range(0, nodenum_half): node[i][1:] = [cylinder_r * math.cos(i * theta), cylinder_r * math.sin(i * theta), 0] for i in range(nodenum_half, nodenum): node[i][1:] = [cylinder_r * math.cos(i * theta), cylinder_r * math.sin(i * theta), cylinder_h] #save the information of facets facenum = nodenum_half + 2 # sides & top facet & bottom facet faceAll = [[0 for col in range(6)] for row in range(facenum-2)] for i in range(0, facenum-3): faceAll[i] = [4, i+1, i+2, i+2+nodenum_half, i+1+nodenum_half, 4] faceAll[facenum-3] = [4, facenum-2, 1, nodenum_half + 1, nodenum, 4] face = [[0 for col in range(5)] for row in range(facenum-2)] faceMark = [[0 for col in range(3)] for row in range(facenum-2)] for i in range(0,facenum-2): face[i] = faceAll[i][0:5] faceMark[i] = [1,0,faceAll[i][-1]] meshsize = [0.1] # the size of mesh numVolumMark = 1 # one region SolventMark = 1 # the region mark is 1 region = [[0 for col in range(6)] for row in range(numVolumMark)] for i in range(0,len(region)): region[i] = [i+1,0,0,0,0,0] region[0][1] = (node[0][1] + node[nodenum_half/2+nodenum_half][1])/2 region[0][2] = (node[0][2] + node[nodenum_half/2+nodenum_half][2])/2 region[0][3] = (node[0][3] + node[nodenum_half/2+nodenum_half][3])/2 region[0][4] = SolventMark region[0][5] = meshsize[0] line = '# Part 1 - node list\n' boxf.write(line) line = '# node count, 3 dim , no attribute, no boundary marker\n' boxf.write(line) line = str(nodenum) + '\t' + '3' + '\t' + '0' + '\t' + '0' + '\n' boxf.write(line) for i in range(0, nodenum): line = str(node[i][0]) + '\t' + str(node[i][1]) + '\t' + str(node[i][2]) + '\t' + str(node[i][3]) + '\n' boxf.write(line) line = '# Part 2 - face list\n' boxf.write(line) line = str(facenum) + '\t' + '1' + '\n' boxf.write(line) line = '# facet count, boundary marker\n' boxf.write(line) # the boundary mark of the bottom facet is 1 line = str(1) + '\t' + str(0) + '\t' + str(1) + '\n'\ boxf.write(line) line = str(nodenum_half) + '\t' for i in range(0, nodenum_half): line += str(i+1) + '\t' line += '\n' boxf.write(line) # the boundary mark of sides is 4 for i in range(0,facenum-2): line = str(faceMark[i][0]) + '\t' + str(faceMark[i][1]) + '\t' + str(faceMark[i][2]) + '\n' boxf.write(line) line = str(face[i][0]) + '\t' + str(face[i][1]) + '\t' + str(face[i][2]) + '\t' + str(face[i][3]) + '\t' + str(face[i][4]) + '\n' boxf.write(line) # the boundary mark of the top facet is 2 line = str(1) + '\t' + str(0) + '\t' + str(2) + '\n' boxf.write(line) line = str(nodenum_half) + '\t' for i in range(0, nodenum_half): line += str(i +1+nodenum_half) + '\t' line += '\n' boxf.write(line) line = '# Part 3 - hole list\n' boxf.write(line) line = '0' + '\n' boxf.write(line) line = '# Part 4 - region list\n' boxf.write(line) line = str(numVolumMark) + '\n' boxf.write(line) for i in range(0,len(region)): line = str(region[i][0]) + '\t' + str(region[i][1]) + '\t' + str(region[i][2]) + '\t' + \ str(region[i][3]) + '\t' + str(region[i][4]) + '\t' + str(region[i][5]) + '\n' boxf.write(line) boxf.close() boxmeshfile = 'cylinder_' + str(cylinder_r) + '_' + str(cylinder_h) + '-' + 'refined1'+ '.mesh' cmd = './tetgen -pq1.414a0.1' + boxname os.system(cmd) cputime_end = time.clock() cputime = cputime_end - cputime_start print 'The total CPU time is %0.3fs' % cputime if __name__ == '__main__': main(sys.argv)
生成圆柱体的组合体:
#generate three cylinders import os import sys import time import math def main(argv): cputime_start = time.clock() #cylinder_r < bulk_r cylinder_r = float(argv[1]) #the radius of the cylinder cylinder_h = float(argv[2]) #the height of the cylinder bulk_r = float(argv[3]) #the radius of the bulk region bulk_h = float(argv[4]) #the height of the bulk region hole_flag = int(argv[5]) # 1 - there is a hole between the bulk region and the cylinder print 'The radius of the cylinder is %0.3f' % cylinder_r print 'The height of the cylinder is %0.3f' % cylinder_h print 'The radius of the bulk region is %0.3f' % bulk_r print 'The height of the bulk region is %0.3f' %bulk_h boxname = 'cylinder' + '-' + str(cylinder_r) + '-' + str(cylinder_h) + '.poly' boxf = open(boxname,'w') theta = math.pi/64 #use a polygon to approximat a circle nodenum_part = 128 nodenum = nodenum_part * 2 * 3 nodenum_half = nodenum_part * 3 #save the information of nodes node = [[0 for col in range(4)] for row in range(nodenum)] for i in range(0,nodenum): node[i] = [i+1,0,0,0] for i in range(0, nodenum_part): node[i][1:] = [bulk_r * math.cos(i * theta), bulk_r * math.sin(i * theta), 0] for i in range(nodenum_part, nodenum_part * 2): node[i][1:] = [bulk_r * math.cos(i * theta), bulk_r * math.sin(i * theta), bulk_h] for i in range(nodenum_part * 2, nodenum_part * 3): node[i][1:] = [cylinder_r * math.cos(i * theta), cylinder_r * math.sin(i * theta), bulk_h] for i in range(nodenum_part * 3, nodenum_part * 4): node[i][1:] = [cylinder_r * math.cos(i * theta), cylinder_r * math.sin(i * theta), cylinder_h + bulk_h] for i in range(nodenum_part * 4, nodenum_part * 5): node[i][1:] = [bulk_r * math.cos(i * theta), bulk_r * math.sin(i * theta), cylinder_h + bulk_h] for i in range(nodenum_part * 5, nodenum_part * 6): node[i][1:] = [bulk_r * math.cos(i * theta), bulk_r * math.sin(i * theta), cylinder_h + bulk_h + bulk_h] #save the information of facets if(hole_flag): facenum = nodenum_half + 4 # sides & top facet & bottom facet & interfaces between two regions else: facenum = nodenum_half + 6 faceAll = [[0 for col in range(6)] for row in range(nodenum_half)] # the boundary mark of sides of the bulk region is 3 for i in range(0, nodenum_part-1): faceAll[i] = [4, i+1, i+2, i+2+nodenum_part, i+1+nodenum_part, 3] faceAll[nodenum_part-1] = [4, nodenum_part, 1, nodenum_part + 1, nodenum_part * 2, 3] # the boundary mark of sides of the cylinder is 4 for i in range(nodenum_part, nodenum_part * 2-1): faceAll[i] = [4, i+1+nodenum_part, i+2+nodenum_part, i+2+2*nodenum_part, i+1+2*nodenum_part, 4] faceAll[nodenum_part*2-1] = [4, 3*nodenum_part, 2*nodenum_part+1, 3 * nodenum_part + 1, nodenum_part * 4, 4] # the boundary mark of sides of the bulk region is 3 for i in range(nodenum_part*2, nodenum_part * 3-1): faceAll[i] = [4, i+1+2*nodenum_part, i+2+2*nodenum_part, i+2+3*nodenum_part, i+1+3*nodenum_part, 3] faceAll[nodenum_part*3-1] = [4, 5*nodenum_part, 4*nodenum_part+1, 5 * nodenum_part + 1, nodenum_part * 6, 3] face = [[0 for col in range(5)] for row in range(nodenum_half)] faceMark = [[0 for col in range(3)] for row in range(nodenum_half)] for i in range(0,nodenum_half): face[i] = faceAll[i][0:5] faceMark[i] = [1,0,faceAll[i][-1]] meshsize = [10.0,1.0,10.0] # the size of mesh numVolumMark = 3 SolventMark = [1,1,1] # region marks of the three regions are all 1 region = [[0 for col in range(6)] for row in range(numVolumMark)] for i in range(0,len(region)): region[i] = [i+1,0,0,0,0,0] region[0][1] = (node[0][1] + node[nodenum_part/2+nodenum_part][1])/2 region[0][2] = (node[0][2] + node[nodenum_part/2+nodenum_part][2])/2 region[0][3] = (node[0][3] + node[nodenum_part/2+nodenum_part][3])/2 region[0][4] = SolventMark[0] region[0][5] = meshsize[0] region[1][1] = (node[2*nodenum_part][1] + node[nodenum_part/2+3*nodenum_part][1])/2 region[1][2] = (node[2*nodenum_part][2] + node[nodenum_part/2+3*nodenum_part][2])/2 region[1][3] = (node[2*nodenum_part][3] + node[nodenum_part/2+3*nodenum_part][3])/2 region[1][4] = SolventMark[1] region[1][5] = meshsize[1] region[2][1] = (node[4*nodenum_part][1] + node[nodenum_part/2+5*nodenum_part][1])/2 region[2][2] = (node[4*nodenum_part][2] + node[nodenum_part/2+5*nodenum_part][2])/2 region[2][3] = (node[4*nodenum_part][3] + node[nodenum_part/2+5*nodenum_part][3])/2 region[2][4] = SolventMark[2] region[2][5] = meshsize[2] line = '# Part 1 - node list\n' boxf.write(line) line = '# node count, 3 dim , no attribute, no boundary marker\n' boxf.write(line) line = str(nodenum) + '\t' + '3' + '\t' + '0' + '\t' + '0' + '\n' boxf.write(line) for i in range(0, nodenum): line = str(node[i][0]) + '\t' + str(node[i][1]) + '\t' + str(node[i][2]) + '\t' + str(node[i][3]) + '\n' boxf.write(line) line = '# Part 2 - face list\n' boxf.write(line) line = str(facenum) + '\t' + '1' + '\n' boxf.write(line) line = '# facet count, boundary marker\n' boxf.write(line) # the boundary mark of the bottom facet is 1 line = str(1) + '\t' + str(0) + '\t' + str(1) + '\n' boxf.write(line) line = str(nodenum_part) + '\t' for i in range(0, nodenum_part): line += str(i+1) + '\t' line += '\n' boxf.write(line) # the boundary mark of sides of the bulk region is 3 for i in range(0,nodenum_part): line = str(faceMark[i][0]) + '\t' + str(faceMark[i][1]) + '\t' + str(faceMark[i][2]) + '\n' boxf.write(line) line = str(face[i][0]) + '\t' + str(face[i][1]) + '\t' + str(face[i][2]) + '\t' + str(face[i][3]) + '\t' + str(face[i][4]) + '\n' boxf.write(line) # the boundary mark of the interface is 5 line = str(2) + '\t' + str(1) + '\t' + str(5) + '\n' boxf.write(line) line = str(nodenum_part) + '\t' for i in range(nodenum_part, 2*nodenum_part): line += str(i+1) + '\t' line +='\n' boxf.write(line) line = str(nodenum_part) + '\t' for i in range(2*nodenum_part, 3*nodenum_part): line += str(i+1) + '\t' line +='\n' boxf.write(line) line = str(1) + '\t' + str(0) + '\t' + str(0) + '\t' + str(bulk_h) + '\n' boxf.write(line) # the boundary mark of the facet on the hole is 6 if(hole_flag==0): line = str(1) + '\t' + str(0) + '\t' + str(6) + '\n' boxf.write(line) line = str(nodenum_part) + '\t' for i in range(2*nodenum_part, 3*nodenum_part): line += str(i+1) + '\t' line +='\n' boxf.write(line) # the boundary mark of sides of the cylinder is 4 for i in range(nodenum_part,2*nodenum_part): line = str(faceMark[i][0]) + '\t' + str(faceMark[i][1]) + '\t' + str(faceMark[i][2]) + '\n' boxf.write(line) line = str(face[i][0]) + '\t' + str(face[i][1]) + '\t' + str(face[i][2]) + '\t' + str(face[i][3]) + '\t' + str(face[i][4]) + '\n' boxf.write(line) # the boundary mark of the interface is 5 line = str(2) + '\t' + str(1) + '\t' + str(5) + '\n' boxf.write(line) line = str(nodenum_part) + '\t' for i in range(4*nodenum_part, 5*nodenum_part): line += str(i+1) + '\t' line +='\n' boxf.write(line) line = str(nodenum_part) + '\t' for i in range(3*nodenum_part, 4*nodenum_part): line += str(i+1) + '\t' line +='\n' boxf.write(line) line = str(1) + '\t' + str(0) + '\t' + str(0) + '\t' + str(bulk_h+cylinder_h) + '\n' boxf.write(line) # the boundary mark of the facet on the hole is 6 if(hole_flag==0): line = str(1) + '\t' + str(0) + '\t' + str(6) + '\n' boxf.write(line) line = str(nodenum_part) + '\t' for i in range(3*nodenum_part, 4*nodenum_part): line += str(i+1) + '\t' line +='\n' boxf.write(line) # the boundary mark of sides of the bulk region is 3 for i in range(2*nodenum_part,3*nodenum_part): line = str(faceMark[i][0]) + '\t' + str(faceMark[i][1]) + '\t' + str(faceMark[i][2]) + '\n' boxf.write(line) line = str(face[i][0]) + '\t' + str(face[i][1]) + '\t' + str(face[i][2]) + '\t' + str(face[i][3]) + '\t' + str(face[i][4]) + '\n' boxf.write(line) # the boundary mark of the top facet is 2 line = str(1) + '\t' + str(0) + '\t' + str(2) + '\n' boxf.write(line) line = str(nodenum_part) + '\t' for i in range(5*nodenum_part, 6*nodenum_part): line += str(i+1) + '\t' line +='\n' boxf.write(line) line = '# Part 3 - hole list\n' boxf.write(line) line = '0' + '\n' boxf.write(line) line = '# Part 4 - region list\n' boxf.write(line) line = str(numVolumMark) + '\n' boxf.write(line) for i in range(0,len(region)): line = str(region[i][0]) + '\t' + str(region[i][1]) + '\t' + str(region[i][2]) + '\t' + \ str(region[i][3]) + '\t' + str(region[i][4]) + '\t' + str(region[i][5]) + '\n' boxf.write(line) boxf.close() #boxmeshfile = 'box_analytic' + '-'+ str(boxWidth) + '-'+ str(boxLength) + '-' + str(boxHeight) + '-' + str(meshsize[0]) + '.mesh' boxmeshfile = 'cylinder_reservoir_' + str(cylinder_r) + '_' + str(cylinder_h) + '-' + 'refine'+ '.mesh' cmd = './tetgen -pq1.414a0.1' + boxname os.system(cmd) cputime_end = time.clock() cputime = cputime_end - cputime_start print 'The total CPU time is %0.3fs' % cputime if __name__ == '__main__': main(sys.argv)
下图中中间圆柱没有上下两个面。
下图中中间圆柱没有两个面,标记为6。
posted on 2019-12-15 22:48 Little-Prince 阅读(2224) 评论(0) 编辑 收藏 举报