Fenics网格文件中子域指示器位置及修改方法问询
网格文件中子域指示器的位置及修改方法
刚好我对Triangle+FEniCS的这套流程很熟悉,给你详细拆解:
一、子域指示器的位置
首先得明确两个阶段的存储位置:
- Triangle生成的原始网格文件:边界子域的标记(也就是你说的子域指示器)存放在
.face文件里,如果你是用.poly文件定义的网格,标记其实是在.poly的边界段部分预先指定的,Triangle生成网格时会把这些标记写入.face。 - 转换后的XML格式文件:经过
dolfin-convert转换后,标记会被保留在XML的<boundary_subdomains>标签下,每个边界面对应的<face>标签里的marker属性,就是子域指示器的数值。
二、修改子域指示器值的三种方法
1. 从Triangle源文件入手(最规范,推荐)
如果你还没生成最终网格,直接在Triangle的.poly文件里定义边界标记是最优解:
- 打开你的
.poly文件,找到第5部分(边界段定义),每一行的格式是:段编号 节点1 节点2 标记值。比如:5 1 1 2 1 # 连接节点1和2的边界段,标记为1(对应第一个Dirichlet区域) 2 2 3 2 # 连接节点2和3的边界段,标记为2(对应第二个Dirichlet区域) 3 3 4 3 # 连接节点3和4的边界段,标记为3(对应第三个Dirichlet区域) - 重新生成网格:运行
triangle -p your_mesh.poly,得到.node、.ele、.face文件; - 转换为XML:执行
dolfin-convert your_mesh.msh your_mesh.xml,此时XML里的边界标记就是你自定义的数值了。
2. 直接修改已生成的XML文件
如果已经有了XML文件,不想重新跑Triangle,可以直接编辑XML:
- 打开XML文件,找到
<boundary_subdomains>节点,里面的每个<face>标签都有marker属性,比如:<boundary_subdomains> <face index="0" marker="1"/> <face index="1" marker="1"/> <face index="2" marker="2"/> </boundary_subdomains> - 直接修改
marker后面的数字,比如把某些face的marker改成3,就能对应你的新边界区域。
3. 在FEniCS代码中动态修改(适合临时调整)
如果不想改动网格文件,也可以在代码里读取网格后重新标记边界:
- 先加载网格和原始边界标记:
from dolfin import * mesh = Mesh("your_mesh.xml") # 加载dolfin-convert生成的边界标记文件 boundaries = MeshFunction("size_t", mesh, mesh.topology().dim()-1) boundaries.read("your_mesh_physical_region.xml") - 自定义边界判断函数,重新标记:
# 比如定义x=0的边界为标记3 class LeftBoundary(SubDomain): def inside(self, x, on_boundary): # 1e-6是浮点精度容错 return on_boundary and abs(x[0]) < 1e-6 left_boundary = LeftBoundary() boundaries.set_all(0) # 先清空所有标记(可选) left_boundary.mark(boundaries, 3) # 将符合条件的边界标记为3 - 之后就可以用这个
boundaries定义Dirichlet条件:bc1 = DirichletBC(V, Constant(0.0), boundaries, 1) bc2 = DirichletBC(V, Constant(1.0), boundaries, 2) bc3 = DirichletBC(V, Constant(2.0), boundaries, 3)
补充一句:Triangle默认会把所有未手动指定的边界标记为1,所以如果之前没在.poly里设置,所有边界的marker都是1,这时候就需要用上面的方法调整啦。
内容的提问来源于stack exchange,提问作者usernumber
相关产品推荐
相关产品推荐

