I’m trying to generate a ring mesh using gmsh for solving NS equation using dolfinx. The mesh looks fine, meaning that the cells are in the desired locations (left panel), but I have a problem with the boundary conditions. The boundaries are not just the inner and outer circles, but also the radial lines that connects them (right panel). How can I fix this?
import gmsh
import os
import numpy as np
import matplotlib.pyplot as plt
from mpi4py import MPI
from dolfinx.io import gmshio
gmsh.initialize()
c_x = c_y = 0.
r1, r2 = 0.5, 1
gdim = 2
mesh_comm = MPI.COMM_WORLD
model_rank = 0
fluid_marker = 1
inner_circle_marker = 3
outer_circle_marker = 4
inner_radius = r1
outer_radius = r2
num_segments = 64
num_radial_divisions = 10
inner_points = []
outer_points = []
for i in range(num_segments):
angle = 2 * np.pi * i / num_segments
inner_points.append(gmsh.model.geo.addPoint(inner_radius * np.cos(angle),
inner_radius * np.sin(angle), 0))
outer_points.append(gmsh.model.geo.addPoint(outer_radius * np.cos(angle),
outer_radius * np.sin(angle), 0))
# Step 2: Create transfinite quadrilateral patches
surfaces = []
inner_circle = []
outer_circle = []
for i in range(num_segments):
# Create lines for one segment of the ring
inner_line = gmsh.model.geo.addLine(inner_points[i], inner_points[(i + 1) % num_segments])
outer_line = gmsh.model.geo.addLine(outer_points[i], outer_points[(i + 1) % num_segments])
radial_line_1 = gmsh.model.geo.addLine(inner_points[i], outer_points[i])
radial_line_2 = gmsh.model.geo.addLine(inner_points[(i + 1) % num_segments],
outer_points[(i + 1) % num_segments])
# Add to circle boundaries (inner and outer circle)
inner_circle.append(inner_line)
outer_circle.append(outer_line)
# Create a curve loop and surface for the quadrilateral patch
loop = gmsh.model.geo.addCurveLoop([inner_line, radial_line_2, -outer_line, -radial_line_1])
surface = gmsh.model.geo.addPlaneSurface([loop])
surfaces.append(surface)
# Set transfinite meshing for the lines (excluding radial lines)
gmsh.model.geo.mesh.setTransfiniteCurve(inner_line, 2) # 2 divisions (1 segment)
gmsh.model.geo.mesh.setTransfiniteCurve(outer_line, 2) # 2 divisions (1 segment)
gmsh.model.geo.mesh.setTransfiniteCurve(radial_line_1, num_radial_divisions + 1)
gmsh.model.geo.mesh.setTransfiniteCurve(radial_line_2, num_radial_divisions + 1)
# Set transfinite meshing for the surface
gmsh.model.geo.mesh.setTransfiniteSurface(surface)
gmsh.model.geo.mesh.setRecombine(2, surface) # Use quadrangles
# Step 3: Create physical groups for the inner and outer circles only (excluding radial lines)
gmsh.model.addPhysicalGroup(1, inner_circle, inner_circle_marker)
gmsh.model.setPhysicalName(1, inner_circle_marker, "Inner Circle")
gmsh.model.addPhysicalGroup(1, outer_circle, outer_circle_marker)
gmsh.model.setPhysicalName(1, outer_circle_marker, "Outer Circle")
# Step 4: Create a physical group for the fluid region (inner and outer circles as fluid)
gmsh.model.geo.synchronize()
gmsh.model.addPhysicalGroup(gdim, surfaces, fluid_marker)
gmsh.model.setPhysicalName(gdim, fluid_marker, "Fluid")
gmsh.model.mesh.generate(gdim)
volumes = gmsh.model.getEntities(dim=gdim)
boundaries = gmsh.model.getBoundary(volumes, oriented=False)
print(len(boundaries))
inner_outer_boundaries = [b for b in boundaries if b[0] == 1 and (gmsh.model.getPhysicalName(1, b[1]) == "Inner Circle" or gmsh.model.getPhysicalName(1, b[1]) == "Outer Circle")]
print(f"Filtered Boundaries (inner and outer circle only): {inner_outer_boundaries}")
assert len(inner_outer_boundaries) == 2, f"Unexpected number of boundaries: {len(inner_outer_boundaries)}"
mesh, _, ft = gmshio.model_to_mesh(gmsh.model, mesh_comm, model_rank, gdim=gdim)
ft.name = "Facet markers"