Mpirun performs mesh generation

Hello, Dear Professor. This is a function that I wrote about generating moving meshes base on Can’t create 1D mesh in parallel, where Ulh is the numerical result of calculations on the original mesh, mesh modification with consistent topology, and this processing is performed serially when running, as well as when running on the original mesh, performance is good. But when I use mpirun -np n python3 my_file.py, If n is greater than 1, it will result in a new grid derangement. What I understand is that the transfer takes place only in the main process, and the data from the other processes is not added to the main process, what should I do? Looking forward to your guidance, thank you.

def get_displacement_at_geometry_nodes(msh, displacement_func):
   

    geom_nodes = msh.geometry.x.copy()  # (N_geom, 3)
    print(f"geom_nodes-Number of nodes: {len(geom_nodes)}")
    
    V_linear = fem.functionspace(msh, ("Lagrange", 1, (3,)))

    disp_linear = fem.Function(V_linear)
    disp_linear.interpolate(displacement_func)
    displacement_at_nodes = disp_linear.x.array.reshape(-1, 3)
    print(f"displacement_at_nodes-Number of nodes: {len(displacement_at_nodes)}")

    if MPI.COMM_WORLD.rank == 0:
        deformed_coords = msh.geometry.x.copy()
        deformed_coords[:] += displacement_at_nodes  # 

        #
        num_nodes = len(deformed_coords)
        print(f"deformed_coords-Number of nodes: {num_nodes}")

        # 
        mesh_obj = displacement_func.function_space.mesh

    
        num_nodes_global = mesh_obj.topology.index_map(mesh_obj.topology.dim).size_global

        cells = msh.topology.connectivity(3, 0)  #
        cell_vertices = cells.array.reshape((-1, 8))  # 
        print(f"deformed_coords---{num_nodes_global}")
    else:
        # 
        cell_vertices = np.empty((0, 8), dtype=np.int64)
        deformed_coords = np.empty((0, 3), dtype=np.float64)

    #
    from basix import CellType as BasixCellType

    #
    # 
    tet_element = ufl.Mesh(element("Lagrange", BasixCellType.hexahedron, 1, shape=(3,)) )

    #
    deformed_mesh = mesh.create_mesh(
        MPI.COMM_WORLD,
        cell_vertices,
        deformed_coords, #dian
        tet_element
    )
    cell_index_map = deformed_mesh.topology.index_map(deformed_mesh.topology.dim)
    print(
        f"Num cells local: {cell_index_map.size_local}\n Num cells global: {cell_index_map.size_global}"
    )

    #
    num_nodes = len(deformed_mesh.geometry.x)
    print(f"number of the nodes: {num_nodes}")
    #
    return disp_linear, deformed_mesh

disp_linear, deformed_mesh = get_displacement_at_geometry_nodes(msh, Ulh)

Can anyone help me? Thanks a million!

If you want to keep the connectivity, and only move the nodes, please consider:

which explains how to move the current mesh nodes, rather than recreating the whole mesh.

1 Like

Thank you for your reply. This part is also what I want to learn, but I need to describe my own problem more clearly. My problem is a linear elastic problem; when there is external pressure, the whole region will be deformed, rather than simply internal node position changes. I think this is part of the content moving grid, not just the internal interface moving. Looking forward to your guidance!

The example above moves the internal nodes based on the data in a dolfinx.fem.Function, which I assume is what you will have as input to your own problem. It doesn’t have any assumptions that would keep the exterior boundary fixed, that is just due to the specifics of the prescribed functions expr and expr2

If u is a solution from a elasticity probloem, you can simply pass that to perturb_mesh(u)

1 Like

I’m sorry. Yes, you are right. In addition, I also have a question: I would like to ask if FEniCSx 0.9.0 has a similar FEniCS support ALE function.

We do not have a specific ALE module in FEniCSx. As you can observe, moving the mesh given a function can be done as above.

If you want to make a smoothen function, for instance by a Laplace smoothing, this is covered in:

NOTE: In the post above it doesn’t use the perturb_mesh, but assumes a 1-1 relationship between the mesh nodes and dofs. I would recommend adapting the code such that it looks like

def deform_mesh(V, bcs: List[dolfinx.fem.DirichletBCMetaClass]):
    mesh = V.mesh
    uh = dolfinx.fem.Function(V)
    dolfinx.fem.petsc.set_bc(uh.vector, bcs)
    u = ufl.TrialFunction(V)
    v = ufl.TestFunction(V)
    a = ufl.inner(ufl.grad(u), ufl.grad(v))*ufl.dx
    L = ufl.inner(dolfinx.fem.Constant(mesh, (0., 0.)), v)*ufl.dx
    problem = dolfinx.fem.petsc.LinearProblem(a, L, bcs, uh)
    problem.solve()
    perturb_mesh(uh) 
1 Like

Thank you for your guidance, which is very helpful to me; then I will do as you say. Thank you again for your patient guidance.