Hi everyone,
I am trying to compute both boundary mesh and a submesh of this boundary mesh from an halfdisk-mesh. I am using gmsh to build the halfdisk mesh.
But plotting the boundary mesh (fenics_halfdisk_bmesh) and part of the boundary mesh (fenics_halfdisk_bmesh_CurvedBoundary), transversal lines appear and I am not sure doing it properly:
- Why do I get transversal lines?
- Could you tell me how to get “well organized” submeshes ?
- Also, when I move the tolerance in the CurvedBoundary() class to lower (e.g. 1E-5) , the halfdisk_bmesh_CurvedBoundary does not contain anything anymore, could you tell me why? / How to choose idoine tolerance in that case?
Please find below the code to reproduce:
from fenics import *
import matplotlib.pyplot as plt
import gmsh
import meshio
import numpy as np
import os
def halfdisk_MSHmesh3D(disk_radius, mesh_resolution, input_MSHmesh_path):
gmsh.initialize()
gmsh.model.add("halfdisk")
gmsh.option.setNumber("Mesh.Algorithm", 5)
gmsh.option.setNumber("Mesh.MeshSizeMin", mesh_resolution)
gmsh.option.setNumber("Mesh.MeshSizeMax", mesh_resolution)
hd = [
gmsh.model.occ.addDisk(0., 0., 0., disk_radius, disk_radius),
gmsh.model.occ.addRectangle(-disk_radius, 0., 0., 2*disk_radius, disk_radius)
]
gmsh.model.occ.intersect([(2, hd[0])], [(2, hd[1])])
gmsh.model.occ.synchronize()
gmsh.model.mesh.generate(2)
gmsh.write(input_MSHmesh_path)
#gmsh.fltk.run()
gmsh.finalize()
mesh = meshio.read(input_MSHmesh_path)
return mesh
def mesh3D_to_mesh2D(mesh, cell_type, prune_z=False):
# code source : https://fenicsproject.discourse.group/t/how-to-use-meshvaluecollection/5106
cells = np.vstack([cell.data for cell in mesh.cells if cell.type==cell_type])
cell_data = np.hstack([mesh.cell_data_dict["gmsh:geometrical"][key]
for key in mesh.cell_data_dict["gmsh:geometrical"].keys() if key==cell_type])
# Remove z-coordinates from mesh if we have a 2D cell and all points have the same third coordinate
points= mesh.points
if prune_z:
points = points[:,:2] # remove z
mesh_new = meshio.Mesh(points=points, cells={cell_type: cells}, cell_data={"name_to_read":[cell_data]})
return mesh_new
def convert_msh_to_xml(MSHmesh_path):
msh = meshio.read(MSHmesh_path)
A = str(os.path.splitext(MSHmesh_path)[0])
B = os.path.splitext(A)[0]
XMLmesh_output_path = str(B + ".xml")
print('xml path = {}'.format(XMLmesh_output_path))
meshio.write(XMLmesh_output_path, meshio.Mesh(points = msh.points, cells = {'triangle': msh.cells_dict['triangle']}))
return XMLmesh_output_path
########
# MAIN #
########
# 2D halfdisk mesh .msh
halfdisk_mesh3D = halfdisk_MSHmesh3D(1., 0.03, "./halfdisk_mesh3D.msh")
# Transform 3D .msh into 2D .msh
halfdisk_mesh2D = mesh3D_to_mesh2D(halfdisk_mesh3D, "triangle", prune_z=True)
meshio.write("./halfdisk_mesh2D.msh", halfdisk_mesh2D)
# Transform 2D .msh into FEniCS readable mesh formats (.xml and Mesh())
XMLmesh2D_output_path = convert_msh_to_xml("./halfdisk_mesh2D.msh")
fenics_halfdisk_mesh2D = Mesh(XMLmesh2D_output_path)
# Plot boundary submesh
fenics_halfdisk_bmesh = BoundaryMesh(fenics_halfdisk_mesh2D, "exterior")
plot(fenics_halfdisk_bmesh, title='Boundaries submesh')
plt.show()
# Plot the circular part of the boundary submesh
class CurvedBoundary(SubDomain):
def inside(self, x, on_boundary):
tol = 1E-3
disk_radius = 1.
return near(sqrt(x[0] * x[0] + x[1] * x[1]), disk_radius, tol) #and on_boundary
fenics_halfdisk_bmesh_CurvedBoundary = SubMesh(fenics_halfdisk_bmesh, CurvedBoundary())
plot(fenics_halfdisk_bmesh_CurvedBoundary, title='Curved Boundary submesh')
plt.show()