我用Gmsh创建了一个网格(一个有孔的表面,然后将其拉伸)。现在我想用例如MatplotlibViewer(Mayavi在我的两台计算机上均无法运行)。我曾希望可以使用mesh.physicalFaces定义一个新的网络,但是如果可能的话,我还没有弄清楚。我的第二次尝试是使用Gmsh将网格再次应用到“拉伸”命令。但是网格不对应于3D版本。有人可以给我一个线索吗?也就像另一种表示方法一样。
我正在使用Win10,Fipy 3.1.3,Python 3.6
import numpy as np
from fipy import *
#%%
def func_mesh():
mesh = Gmsh3D('''
Geometry.OCCAutoFix = 0;
SetFactory("OpenCASCADE");
x = 1.;
bseg = 0.08;
bs= bseg*x;
ls = 2.1;
cl = 0.01;
radius = 0.006;
// Exterior (bounding box) of mesh
Point(1) = {0, 0, 0, cl};
Point(2) = {0, bs, 0, cl};
Point(4) = { bs, 0, 0, cl};
Point(3) = {bs, bs, 0, cl};
Line(1) = {1, 2};
Line(2) = {2, 3};
Line(3) = {3, 4};
Line(4) = {4, 1};
Line Loop (21) = {1,2,3,4};
//Circle
Point(5) = {bseg/2 - radius, bseg/2, 0, cl};
Point(6) = {bseg/2, bseg/2 + radius, 0, cl};
Point(7) = { bseg/2 + radius, bseg/2, 0, cl};
Point(8) = {bseg/2, bseg/2 - radius, 0, cl};
Point(9) = {bseg/2, bseg/2, 0, cl};
Circle(10) = {5,9,6};
Circle(11) = {6,9,7};
Circle(12) = {7,9,8};
Circle(13) = {8,9,5};
Line Loop(22) = {10,11,12,13};
Plane Surface(40) = {22}; //cycl
Plane Surface(15) = {21, 22}; //Surface with a hole
id[] = Extrude {0, 0, ls} {Surface{15}; Layers{210}; Recombine;};
Surface Loop(2) = {46, 45, 48, 47, 49, 41, 44, 43, 42, 15};
Physical Volume("Vol") = {id[]};
Physical Surface("surf_ges") = {41, 42, 43, 44, 49, 47, 45, 48, 46, 15};
Physical Surface("HX") = {45, 46, 48, 47};
Physical Surface("Extr") = {15};
''')
return mesh
mesh = func_mesh()
x,y,z = mesh.cellCenters
X,Y,Z = mesh.faceCenters
tS = CellVariable(name="storage",
mesh=mesh,
value=367.,
hasOld=True)
submesh = mesh.physicalFaces['Extr']
xsub, ysub = submesh.cellCenters
tSslice = CellVariable(name = 'tSsclice',
mesh = submesh,
value = tS[z== z[0]])
viewer = MatplotlibViewer(vars = tSslice)
此尝试失败的错误消息是:AttributeError:'binOp'对象没有属性'cellCenters'。 如果仅在拉伸命令之前重新定义网格,则会得到: 由于tSslice的形状,导致出现“ ValueError:太多值无法解包(预期2)”。 感谢您的帮助
答案 0 :(得分:1)
submesh
不是Mesh
;这是一个遮罩,用于识别mesh
的哪些面包含在表面Extr
中。
FiPy无法从另一个网格中提取网格。使用Mesh2D
掩码submesh
和mesh.vertexCoords
创建mesh.faceVertexIDs
应该是可行的,但这并不简单。
从理论上讲,您可以调用Gmsh2D
直到Plane Surface(15) = {21, 22}; //Surface with a hole
的所有内容,但是我发现生成的元素数量与z == z[0]
处的3D切片数量不同。
啊,我明白了。我以为Extrude
操作导致了棱柱形单元,但事实并非如此。细胞是四面体的。由于mesh
的像元并非都具有相同的四面体几何形状,因此不能保证所有以Extr
为基础的像元都位于z == z[0]
的中心。更好的方法是使用FiPy的CellVariable
插值在tS
的坐标处提取tSslice
的值:
from fipy import *
geo = '''
Geometry.OCCAutoFix = 0;
SetFactory("OpenCASCADE");
x = 1.;
bseg = 0.08;
bs= bseg*x;
ls = 2.1;
cl = 0.01;
radius = 0.006;
// Exterior (bounding box) of mesh
Point(1) = {0, 0, 0, cl};
Point(2) = {0, bs, 0, cl};
Point(4) = { bs, 0, 0, cl};
Point(3) = {bs, bs, 0, cl};
Line(1) = {1, 2};
Line(2) = {2, 3};
Line(3) = {3, 4};
Line(4) = {4, 1};
Line Loop (21) = {1,2,3,4};
//Circle
Point(5) = {bseg/2 - radius, bseg/2, 0, cl};
Point(6) = {bseg/2, bseg/2 + radius, 0, cl};
Point(7) = { bseg/2 + radius, bseg/2, 0, cl};
Point(8) = {bseg/2, bseg/2 - radius, 0, cl};
Point(9) = {bseg/2, bseg/2, 0, cl};
Circle(10) = {5,9,6};
Circle(11) = {6,9,7};
Circle(12) = {7,9,8};
Circle(13) = {8,9,5};
Line Loop(22) = {10,11,12,13};
Plane Surface(40) = {22}; //cycl
Plane Surface(15) = {21, 22}; //Surface with a hole
id[] = Extrude {0, 0, ls} {Surface{15}; Layers{210}; Recombine;};
Surface Loop(2) = {46, 45, 48, 47, 49, 41, 44, 43, 42, 15};
Physical Volume("Vol") = {id[]};
Physical Surface("Extr") = {15};
'''
mesh = Gmsh3D(geo + '''
Physical Surface("surf_ges") = {41, 42, 43, 44, 49, 47, 45, 48, 46, 15};
Physical Surface("HX") = {45, 46, 48, 47};
'''
)
submesh = Gmsh2D(geo)
x,y,z = mesh.cellCenters
X,Y = submesh.cellCenters[..., submesh.physicalCells['Extr']]
Z = numerix.ones(X.shape) * z[0]
tS = CellVariable(name="storage",
mesh=mesh,
value=mesh.x * mesh.y * mesh.z,
hasOld=True)
tSslice = CellVariable(name = 'tSsclice',
mesh = submesh)
# interpolate values of tS at positions of tSslice
tSslice[..., submesh.physicalCells['Extr']] = tS(numerix.vstack([X, Y, Z]))
viewer = MatplotlibViewer(vars = tSslice)
在这里,我使用相同的.geo
脚本来定义mesh
和submesh
。我仅将surf_ges
和HX
物理表面添加到mesh
的定义中,因为否则所有这些面也将被导入到submesh
中,尽管有效的{ {1}}的值为0,因此它们会掩盖您感兴趣的面孔。
坦率地说,我认为通过3D数据实现切片的一种更好的方法是使用自定义的MayaviClient(例如,请参见Cahn-Hilliard sphere和sphereDaemon.py
)或导出使用VTKViewer,然后使用诸如ParaView,VisIt或Mayavi之类的工具呈现数据切片。