Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Serendipity (order 2) coordinate elements #3662

Merged
merged 6 commits into from
Mar 15, 2025

Conversation

jorgensd
Copy link
Member

Adds the missing pieces for being able to use S2 (serendipity 2) elements as coordinate elements, and read the meshes to and from XDMF.
MWE

from mpi4py import MPI
import dolfinx
import numpy as np
import basix.ufl

filename = "serendipity.xdmf"

if MPI.COMM_WORLD.rank == 0:
    mesh = dolfinx.mesh.create_unit_square(MPI.COMM_SELF, 10, 12, cell_type=dolfinx.cpp.mesh.CellType.quadrilateral)
    #mesh = dolfinx.mesh.create_unit_cube(MPI.COMM_SELF, 3, 4,5  , cell_type=dolfinx.cpp.mesh.CellType.hexahedron)
    num_cells = mesh.topology.index_map(mesh.topology.dim).size_local
    mesh.topology.create_connectivity(1, mesh.topology.dim)

    edge_map = mesh.topology.index_map(1)
    num_edges_local = edge_map.size_local

    midpoints = dolfinx.mesh.compute_midpoints(mesh, 1, np.arange(num_edges_local, dtype=np.int32))

    org_nodes = mesh.geometry.x

    connectivity = mesh.geometry.dofmap
    num_edges_per_cell = dolfinx.cpp.mesh.cell_num_entities(mesh.topology.cell_type,1)
    new_connectivity = np.zeros((num_cells, connectivity.shape[1] + num_edges_per_cell ), dtype=np.int64)
    new_connectivity[:,:connectivity.shape[1]] = connectivity

    mesh.topology.create_connectivity(mesh.topology.dim, 1)
    c_to_e = mesh.topology.connectivity(mesh.topology.dim,1).array.copy().reshape(-1, num_edges_per_cell)
    node_offset = org_nodes.shape[0]
    c_to_e += node_offset
    new_connectivity[:,connectivity.shape[1]:] = c_to_e
    new_nodes = np.vstack([org_nodes, midpoints])[:,:mesh.geometry.dim]

    coord_el = basix.ufl.element(
    basix.ElementFamily.serendipity,
    mesh.basix_cell(),
    2,
    lagrange_variant=basix.LagrangeVariant.equispaced,
    dpc_variant=basix.DPCVariant.simplex_equispaced,
    shape=(mesh.geometry.dim,),
)

    new_mesh = dolfinx.mesh.create_mesh(MPI.COMM_SELF, new_connectivity, new_nodes, coord_el)


    new_coords = new_mesh.geometry.x
    new_coords[:, 0] += 0.2*np.sin(new_coords[:,1])
    new_coords[:, 1] += 0.1*np.cos(new_coords[:,0])
    import ufl
    print(dolfinx.fem.assemble_scalar(dolfinx.fem.form(1*ufl.dx(domain=new_mesh))))
    with dolfinx.io.XDMFFile(MPI.COMM_SELF, filename, "w") as xdmf:
        xdmf.write_mesh(new_mesh)

MPI.COMM_WORLD.Barrier()
with dolfinx.io.XDMFFile(MPI.COMM_WORLD, filename, "r") as xdmf:
    mesh2 = xdmf.read_mesh()

with dolfinx.io.XDMFFile(MPI.COMM_WORLD, "output.xdmf", "w") as xdmf:
    xdmf.write_mesh(mesh2)

2D:
image
3D:
image

@garth-wells garth-wells enabled auto-merge March 15, 2025 08:10
@garth-wells garth-wells added this pull request to the merge queue Mar 15, 2025
@garth-wells garth-wells changed the title Alternative coordinate element for quads and hexes Add support Serendipity (order 2) coordinate elements Mar 15, 2025
@garth-wells garth-wells added the enhancement New feature or request label Mar 15, 2025
@garth-wells garth-wells changed the title Add support Serendipity (order 2) coordinate elements Add support for Serendipity (order 2) coordinate elements Mar 15, 2025
Merged via the queue into main with commit 8297a31 Mar 15, 2025
28 checks passed
@garth-wells garth-wells deleted the dokken/alternative-coordinate-element branch March 15, 2025 09:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants