Hi,
I am trying to do non matching mesh interpolation between 2 different 3D second ordered meshes. I add a slight random shift on the points of one mesh and do nothing on the other mesh. The GJK error always appear. I am using dolfinx version 0.8.0 installed with conda forge. Here is my MWE:
import gmsh
import dolfinx
from dolfinx import cpp
from dolfinx.mesh import GhostMode
from basix.ufl import element
from dolfinx.fem import Function, functionspace, create_nonmatching_meshes_interpolation_data
from dolfinx.io import XDMFFile
from mpi4py import MPI
import numpy as np
def create_mesh(L, W, H, gdim=3, mesh_order=2, mesh_size=4):
model_rank = 0
if MPI.COMM_WORLD.rank == model_rank:
gmsh.model.add('model')
factory = gmsh.model.occ
factory.add_rectangle(0, 0, 0, L, W)
factory.synchronize()
ov = gmsh.model.get_entities(2)
factory.extrude(ov, 0, 0, H)
factory.synchronize()
ov = gmsh.model.get_entities(gdim)
ps = gmsh.model.addPhysicalGroup(gdim, [item[1] for item in ov])
gmsh.model.setPhysicalName(gdim, ps, "fluid")
gmsh.option.setNumber('Mesh.Algorithm3D', 10)
gmsh.option.setNumber("General.NumThreads", 16)
gmsh.option.setNumber("Mesh.MeshSizeMin", mesh_size)
gmsh.option.setNumber("Mesh.MeshSizeMax", mesh_size)
gmsh.option.setNumber("General.Verbosity", 2)
gmsh.model.mesh.generate(gdim)
gmsh.model.mesh.setOrder(mesh_order)
mesh, _, _ = dolfinx.io.gmshio.model_to_mesh(gmsh.model, MPI.COMM_WORLD, model_rank, gdim=gdim, partitioner=cpp.mesh.create_cell_partitioner(GhostMode.shared_facet))
return mesh
def nmm_interpolate(f_out, f_in):
interpolation_data=create_nonmatching_meshes_interpolation_data(
f_out.function_space.mesh,
f_out.function_space.element,
f_in.function_space.mesh,
padding=1e-11)
f_out.interpolate(f_in,nmm_interpolation_data=interpolation_data)
def create_function_space(mesh, mesh_order):
Pv = element("Lagrange", mesh.basix_cell(), mesh_order, shape=(mesh.geometry.dim,))
V = functionspace(mesh, Pv)
return V
def deform_the_mesh(msh, V):
movement = Function(V)
movement.x.array[:] += np.random.rand(movement.x.array.size) * 0.1
msh.geometry.x[:, :msh.geometry.dim] += movement.x.array.reshape((-1, msh.geometry.dim))
if MPI.COMM_WORLD.rank == 0:
gmsh.initialize()
mesh_order = 2
L, W, H = 50.0, 50.0, 50.0
for i in range(0, 10):
# define function on mesh_0
mesh_0 = create_mesh(L, W, H, gdim=3, mesh_order=mesh_order, mesh_size=4)
V0 = create_function_space(mesh_0, mesh_order)
f0 = Function(V0)
# define function on mesh_new
mesh_new = create_mesh(L, W, H, gdim=3, mesh_order=mesh_order, mesh_size=4)
V_new = create_function_space(mesh_new, mesh_order)
f_new = Function(V_new)
# deform mesh_new with a very slight random shift
deform_the_mesh(mesh_new, V_new)
# interpolation from mesh_0 to mesh_new and inverse
nmm_interpolate(f_new, f0)
if MPI.COMM_WORLD.rank == 0:
print("nmm_interpolate ok", flush = True)
nmm_interpolate(f0, f_new)
if MPI.COMM_WORLD.rank == 0:
print("inverse nmm_interpolate ok", flush = True)
The error message goes like:
nmm_interpolate ok
Traceback (most recent call last):
File "/data/nas_rxtd1/Lingyue/iso_parametric/MWE_3.py", line 82, in <module>
nmm_interpolate(f0, f_new)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/nas_rxtd1/Lingyue/iso_parametric/MWE_3.py", line 40, in nmm_interpolate
interpolation_data=create_nonmatching_meshes_interpolation_data(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/shenlingyue/miniconda3/envs/fenicsx080/lib/python3.12/site-packages/dolfinx/fem/__init__.py", line 93, in create_nonmatching_meshes_interpolation_data
*_create_nonmatching_meshes_interpolation_data(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
RuntimeError: GJK error - max iteration limit reached
What I am confused is that nmm_interpolate(f_new, f0)
works just fine. but I can’t do it inversely: nmm_interpolate(f0, f_new)
Could you please explain why could this happen and how to fix the problem?