Hello everyone,
I am interested in using second-order triangular meshes in legacy FEniCS, but such an application seems to be only found in the UnitDiscMesh
function. I have two questions regarding this:
- Is it possible to create a second-order triangular mesh using two numpy arrays of
vertex
andcell
through MeshEditor()? I have found that this is implemented inUnitDiscMesh.cpp
, but it appears that the Python version does not have a method likeeditor.add_entity_point()
to add edge-based points. When I attempt to create a mesh using onlyeditor.add_vertex()
andeditor.add_cell()
, the resulting mesh seems invalid. The MWE is as follows:
import numpy as np
from fenics import *
tdim, gdim, degree = 2, 2, 2
mesh, editor = Mesh(), MeshEditor()
vertex = np.array([[0, 0], [1, 0], [0, 1],
[0.5, 0], [0, 0.5], [1, 1]])
cell = np.array([[0, 1, 2, 3, 4, 5]])
editor.open(mesh, "triangle", tdim, gdim, degree)
editor.init_vertices(len(vertex))
for i in range(len(vertex)):
editor.add_vertex(i, vertex[i, :])
editor.init_cells(len(cell))
for i in range(len(cell)):
editor.add_cell(i, cell[i, :])
editor.close()
with XDMFFile("text.xdmf") as outfile:
outfile.write(mesh)
- Also, I can first generate a second-order triangular mesh using Gmsh with
circle.geo
and then convertcircle.msh
tocircle.xdmf
using meshio. However, the mesh data read through XDMFFile appears to be corrupted, and the difference betweencircle_out.xdmf
andcircle.xdmf
can be seen in ParaView. The MWE is as follows:
This is my circle.geo
file:
SetFactory("OpenCASCADE");
a = 0;
b = 0;
r = 1;
N = 6;
Circle(1) = {a, b, 0, r, 0, 2*Pi};
Curve Loop(1) = {1};
Plane Surface(1) = {1};
Physical Surface(1) = {1};
Transfinite Curve {1} = N+1 Using Progression 1;
This is my circle.msh
file:
$MeshFormat
2.2 0 8
$EndMeshFormat
$Nodes
19
1 1 0 0
2 0.4999999999999988 0.8660254037844394 0
3 -0.5000000000000021 0.8660254037844374 0
4 -1 -1.20980699416795e-15 0
5 -0.4999999999999981 -0.8660254037844397 0
6 0.5000000000000009 -0.8660254037844382 0
7 0.8660254037844383 0.5000000000000007 0
8 -1.937171126634163e-15 1 0
9 -0.8660254037844396 0.4999999999999984 0
10 -0.8660254037844377 -0.5000000000000017 0
11 1.592665886326894e-15 -1 0
12 0.8660254037844388 -0.4999999999999997 0
13 -4.077392162158101e-16 -1.425974687551479e-16 0
14 0.4999999999999997 -7.129873437757396e-17 0
15 0.2500000000000003 -0.4330127018922191 0
16 0.2499999999999992 0.4330127018922196 0
17 -0.2499999999999993 -0.4330127018922199 0
18 -0.5000000000000002 -6.762022314615491e-16 0
19 -0.2500000000000012 0.4330127018922186 0
$EndNodes
$Elements
6
1 9 2 1 1 1 13 6 14 15 12
2 9 2 1 1 2 13 1 16 14 7
3 9 2 1 1 5 13 4 17 18 10
4 9 2 1 1 6 13 5 15 17 11
5 9 2 1 1 3 13 2 19 16 8
6 9 2 1 1 4 13 3 18 19 9
$EndElements
This is my Python code:
import meshio
def create_mesh(mesh, cell_type, data_name="name_to_read", prune_z=False):
cells = mesh.get_cells_type(cell_type)
cell_data = mesh.get_cell_data("gmsh:physical", cell_type)
points = mesh.points[:,:2] if prune_z else mesh.points
out_mesh = meshio.Mesh(points=points, cells={cell_type:cells}, cell_data={data_name:[cell_data]})
return out_mesh
mesh_from_file = meshio.read("circle.msh")
mesh_triangle = create_mesh(mesh_from_file, "triangle6", prune_z=True)
meshio.write("circle.xdmf", mesh_triangle)
from fenics import *
mesh = Mesh()
with XDMFFile("circle.xdmf") as infile:
infile.read(mesh)
with XDMFFile("circle_out.xdmf") as outfile:
outfile.write(mesh)
Alternatively, are there other ways to use second-order triangular meshes in legacy FEniCS besides UnitDiscMesh
? I am aware that FEniCSx has advantages in supporting higher-order meshes, but due to certain historical reasons, I am currently still using legacy FEniCS. I would greatly appreciate any assistance.