Dear @Monisaddam,
Please note that you have only provided images, leaving it to me to interpret what the spacing between each cell is.
Here I have extracted the relevant code from the post I previously referred to to illustrate how to do this:
"""
Move mesh based on geometrical function
Author: Jørgen S. Dokken and Henrik N.T. Finsberg
SPDX-License-Identifier: MIT
"""
from mpi4py import MPI
import dolfinx
import numpy as np
def vertex_to_dof_map_vectorized(V):
"""Create a map from the vertices of the mesh to the corresponding degree of freedom."""
mesh = V.mesh
num_vertices_per_cell = dolfinx.cpp.mesh.cell_num_entities(
mesh.topology.cell_type, 0
)
dof_layout2 = np.empty((num_vertices_per_cell,), dtype=np.int32)
for i in range(num_vertices_per_cell):
var = V.dofmap.dof_layout.entity_dofs(0, i)
assert len(var) == 1
dof_layout2[i] = var[0]
num_vertices = (
mesh.topology.index_map(0).size_local + mesh.topology.index_map(0).num_ghosts
)
c_to_v = mesh.topology.connectivity(mesh.topology.dim, 0)
assert (c_to_v.offsets[1:] - c_to_v.offsets[:-1] == c_to_v.offsets[1]).all(), (
"Single cell type supported"
)
vertex_to_dof_map = np.empty(num_vertices, dtype=np.int32)
vertex_to_dof_map[c_to_v.array] = V.dofmap.list[:, dof_layout2].reshape(-1)
return vertex_to_dof_map
def perturb_mesh(u: dolfinx.fem.Function):
"""Perturb the mesh based on the displacement function."""
V = u.function_space
mesh = V.mesh
tdim = mesh.topology.dim
vertex_to_dof_map = vertex_to_dof_map_vectorized(V)
mesh.topology.create_connectivity(0, tdim)
num_vertices = (
mesh.topology.index_map(0).size_local + mesh.topology.index_map(0).num_ghosts
)
vertex_to_node_map = dolfinx.mesh.entities_to_geometry(
mesh, 0, np.arange(num_vertices, dtype=np.int32)
).reshape(-1)
u_values = u.x.array.reshape(-1, mesh.geometry.dim)
gdim = mesh.geometry.dim
mesh.geometry.x[vertex_to_node_map, :gdim] += u_values[vertex_to_dof_map, :]
if __name__ == "__main__":
N = 25
# Create parent mesh and mock displacement
mesh = dolfinx.mesh.create_unit_square(
MPI.COMM_WORLD, N, N, cell_type=dolfinx.mesh.CellType.quadrilateral
)
V = dolfinx.fem.functionspace(mesh, ("Lagrange", 1, (mesh.geometry.dim,)))
def expr(x):
move_1 = x[1] * (0.5 - x[1]) * (x[1] < 0.5)
move_2 = (x[1] - 1) * (x[1] - 0.5) * (x[1] > 0.5)
return (np.zeros(x.shape[1]), move_1 + move_2)
u = dolfinx.fem.Function(V)
u.interpolate(expr)
perturb_mesh(u)
# Create the dof -> vertex map and vertex->node map
with dolfinx.io.XDMFFile(mesh.comm, "moved_mesh.xdmf", "w") as xdmf:
xdmf.write_mesh(mesh)
# Reset mesh
u.x.array[:] *= -1
perturb_mesh(u)
def expr2(x, eps=1e-8):
xi = np.floor(x[0] * N)
yi = np.floor(x[1] * N)
move_x = (
0.2
/ N
* np.cos(10 * np.pi * x[0])
* (x[1] > eps)
* (x[1] < 1 - eps)
* (-1) ** yi
)
move_y = (
0.2
/ N
* np.cos(10 * np.pi * x[1])
* (x[0] > eps)
* (x[0] < 1 - eps)
* (-1) ** xi
)
return (move_y, move_x)
u.interpolate(expr2)
perturb_mesh(u)
with dolfinx.io.XDMFFile(mesh.comm, "new_moved_mesh.xdmf", "w") as xdmf:
xdmf.write_mesh(mesh)
which yields
you can of course adapt these movement fields to suite your needs.
For further questions, I would like you to make an effort and at least try to make a minimal example illustrating what you have tried, and what didn’t work.