Hello,
I recently moved from dolfinx 0.6.0
to dolfinx 0.7.3
, by installing adios4dolfinx
ADIOS4DOLFINx - A framework for checkpointing in DOLFINx — ADIOS2Wrappers via conda.
In the following example, I create a mesh via GMSH
and define cell and surface tags.
I then import everything in dolfinx
by using io.gmshio.model_to_mesh
.
Finally, I save mesh, cell tags and facet tags in a XDMF
file.
I run the script in parallel, for instance by using mpirun -n 5
.
My problem:
I would like to read back the same mesh and meshtags, distributed in the same fashion among the 5 ranks. It worked out of the box with dolfinx 0.6.0
, but it does not seem to be the case with dolfinx 0.7.3
.
In the following example, the boundary dofs distributed among the 5 ranks are different when:
-
I save the mesh and then compute
boundary_dofs
(save = True
) -
I load mesh and meshtags from the
XDMF
file and then compute theboundary_dofs
(save = False
)
I tried to do a similar thing by using adios4dolfinx
but I run into the same issue.
Could you please help me?
Many thanks
import gmsh
from dolfinx import io, fem
import os, shutil, sys
import petsc4py
from mpi4py import MPI
petsc4py.init(sys.argv)
comm = MPI.COMM_WORLD
dim = 3
volume_tag = 1
surface_tag = 10
save = True
test_dir = os.path.join(os.getcwd(),'test')
if save:
# Save mesh and meshtags
if comm.rank == 0:
print('Saving ...', flush = True)
if os.path.isdir(test_dir):
shutil.rmtree(test_dir)
os.makedirs(test_dir)
# Create mesh
gmsh.initialize()
gmsh.option.setNumber("General.Terminal", 0)
model = gmsh.model()
model.add("Domain")
model.occ.addBox(0, 0, 0, 8, 8, 8)
model.occ.synchronize()
model.addPhysicalGroup(dim, [1], volume_tag)
model.setPhysicalName(dim, volume_tag, "Domain volume")
boundary_dimtags = model.getBoundary([(dim, 1)], oriented=False)
model.addPhysicalGroup(dim-1, [dt[1] for dt in boundary_dimtags], tag=surface_tag)
model.setPhysicalName(dim-1, surface_tag, "Domain surface")
gmsh.option.setNumber("Mesh.CharacteristicLengthMax", 8/13)
model.occ.synchronize()
model.mesh.generate(dim)
domain, cell_tags, facet_tags = io.gmshio.model_to_mesh(model, comm, rank=0, gdim=dim)
with io.XDMFFile(comm, test_dir+'/domain.xdmf', "w") as xdmf:
xdmf.write_mesh(domain)
cell_tags.name = "cell_tags"
facet_tags.name = "facet_tags"
xdmf.write_meshtags(cell_tags, domain.geometry)
xdmf.write_meshtags(facet_tags, domain.geometry)
xdmf.close()
else:
# Load mesh and meshtags
if comm.rank == 0:
print('Loading ...', flush = True)
with io.XDMFFile(comm, test_dir+'/domain.xdmf', "r") as xdmf:
domain = xdmf.read_mesh()
tdim = domain.topology.dim
fdim = tdim - 1
domain.topology.create_connectivity(fdim, tdim)
cell_tags = xdmf.read_meshtags(domain, name = "cell_tags")
facet_tags = xdmf.read_meshtags(domain, name = "facet_tags")
assert cell_tags.name == "cell_tags"
assert facet_tags.name == "facet_tags"
# Compute boundary_dofs
Vp = fem.FunctionSpace(domain,("CG", 1))
boundary_dofs = fem.locate_dofs_topological(Vp, domain.topology.dim-1, facet_tags.find(surface_tag))
# boundary_dofs is different when the mesh is computed versus loaded
print('Rank = {}, self.boundary_dofs = {}\n\n'.format(comm.rank, boundary_dofs))