So the issue here is that you are making certain assumptions when you use a built in mesh.
A “built in” mesh is created as any other mesh, as set of points and connectivities as two separate arrays
These cells and points are sent to a mesh partitioner of choice (default is SCOTCH), which partitions the mesh. The mesh keeps track of its input index (under mesh.topology.original_cell_index
).
These are in turn used to read in MeshTags
of various dimensions.
However, when a mesh is written to file, we do not revert it to its original indices. It is then written in a continuous fashion, as this is the most efficient.
This means that whenever you read in that mesh from file, the cells are shuffled before they are sent to the mesh partitioner.
This means that there is no direct mapping between the mesh generated with create_unit_square
and the one read from file.
You can see that xdmf and adios2 treats the mesh similarly, by calling:
from mpi4py import MPI
import dolfinx
from dolfinx.fem import (Function, FunctionSpace, Expression)
from dolfinx.io import XDMFFile
import ufl
from petsc4py import PETSc
import adios4dolfinx
comm = MPI.COMM_WORLD
mesh = dolfinx.mesh.create_unit_square(comm, 10, 10, cell_type=dolfinx.mesh.CellType.triangle)
filename = f"./{comm.size}proc.bp"
### write ###
v_cg2 = ufl.VectorElement("Lagrange", mesh.ufl_cell(), 2)
V = FunctionSpace(mesh, v_cg2)
u = Function(V)
x = ufl.SpatialCoordinate(mesh)
dfnx_expr = Expression(x, V.element.interpolation_points())
u.interpolate(dfnx_expr)
adios4dolfinx.write_mesh(mesh, "./mesh/square.bp")
adios4dolfinx.write_function(u, filename)
### write mesh ###
with dolfinx.io.XDMFFile(comm, "mesh.xdmf", "w") as xdmf:
xdmf.write_mesh(mesh)
top = xdmf.read_topology_data()
### read ###
with dolfinx.io.XDMFFile(comm, "mesh.xdmf", "r") as xdmf:
mesh_xdmf = xdmf.read_mesh()
mesh_new = adios4dolfinx.read_mesh(comm, "./mesh/square.bp", "BP4", dolfinx.mesh.GhostMode.none)
print(comm.rank,
"mesh input index", mesh.topology.original_cell_index, "\n",
mesh_new.topology.original_cell_index, "\n",
"\n",
mesh_xdmf.topology.original_cell_index)
v_new = ufl.VectorElement("Lagrange", mesh_new.ufl_cell(), 2)
W = FunctionSpace(mesh_new, v_new)
w = Function(W)
adios4dolfinx.read_function(w, filename)
#adios4dolfinx.read_function(v, filename)
with XDMFFile(comm, f"./0_{comm.size}proc.xdmf", "w") as xdmf:
xdmf.write_mesh(mesh_new)
xdmf.write_function(w)
with XDMFFile(comm, f"./1_{comm.size}proc.xdmf", "w") as xdmf:
xdmf.write_mesh(mesh)
xdmf.write_function(u)
with XDMFFile(comm, f"./2_{comm.size}proc.xdmf", "w") as xdmf:
xdmf.write_mesh(mesh)
xdmf.write_function(w)
with XDMFFile(comm, f"./3_{comm.size}proc.xdmf", "w") as xdmf:
xdmf.write_mesh(mesh_xdmf)
xdmf.write_function(w)
Here, the third example (the mesh read from XDMF) gives the correct output.