Hello everyone,
I’m currently facing an issue with importing a .msh file, generated with Gmsh, into FEniCSx. The challenge lies in accurately defining the physical domains and surfaces created in Gmsh, which are crucial for specifying the integrands of dx and ds.
While resolving this problem is relatively straightforward in FEniCS, I’ve encountered difficulties in FEniCSx, particularly in defining tetrahedral and triangular meshes. Below is the approach I’ve taken so far:
1. Mesh Creation and Conversion:
- Using meshio, I read the .msh file and extracted tetrahedral and triangular cells along with their corresponding physical domain information.
2. Mesh Manipulation:
- I converted the mesh data into formats compatible with FEniCSx and saved them as XDMF files.
import numpy as np
from mpi4py import MPI
from petsc4py import PETSc
from dolfinx import *
from dolfinx.mesh import *
from dolfinx.cpp.mesh import *
from dolfinx.io import *
from dolfinx.la import *
from ufl import *
import meshio
path = "/home/"
filename = "3Dmesh"
mesh = meshio.read(path + filename + ".msh")
def create_mesh(mesh, cell_type, prune_z=False):
cells = mesh.get_cells_type(cell_type)
cell_data = mesh.get_cell_data("gmsh:physical", cell_type)
out_mesh = meshio.Mesh(points=mesh.points, cells={
cell_type: cells}, cell_data={"name_to_read": [cell_data]})
if prune_z:
out_mesh.prune_z_0()
return out_mesh
tetra_mesh = create_mesh(mesh, "tetra")
triangle_mesh = create_mesh(mesh, "triangle")
meshio.write(path + filename + "_tetra.xdmf", tetra_mesh)
meshio.write(path + filename + "_triangle.xdmf", triangle_mesh)
3. Defining Mesh Functions:
- In FEniCS, I could readily define mesh functions using the imported mesh data. However, in FEniCSx, this process seems to present challenges.
mesh = Mesh()
mvc_3d = MeshValueCollection("size_t", mesh, 3)
with XDMFFile(path + filename + "_tetra.xdmf") as infile:
infile.read(mvc_3d, "name_to_read")
mf_3d = cpp.mesh.MeshFunctionSizet(mesh, mvc_3d)
mvc_2d = MeshValueCollection("size_t", mesh, 2)
with XDMFFile(path + filename + "_triangle.xdmf") as infile:
infile.read(mvc_2d, "name_to_read")
mf_2d = cpp.mesh.MeshFunctionSizet(mesh, mvc_2d)
4. Integration Measures:
- The ultimate goal is to define integration measures such as dx and ds, which require accurate subdomain data.
ds = Measure("ds",domain=mesh, subdomain_data=mf_2d)
dS_c = Measure("dS",domain=mesh, subdomain_data=mf_2d)
dx = Measure("dx",domain=mesh, subdomain_data=mf_3d)
Currently, I’m stuck at the step of defining mesh functions and integrating over the domains and boundaries using FEniCSx.
Would anyone have insights or suggestions on how to address this issue in FEniCSx? Any help or guidance would be greatly appreciated.
Thank you!