I need to create stuctured uniform, structuted non-uniform, and unstructured mesh in 2D

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.

1 Like