Geometry, topology and tags#

cmap#

fenicsx_compat.cmap(mesh) -> dolfinx.fem.CoordinateElement

The coordinate element of the mesh geometry.

DOLFINx

Native

0.10

mesh.geometry.cmap

0.11, main

mesh.geometry.cmaps[0]. mesh.geometry.cmap still works but emits a DeprecationWarning.

cell = 0
nodes = mesh.geometry.x[fenicsx_compat.dofmap(mesh)[cell]]
X = fenicsx_compat.cmap(mesh).pull_back(np.array([[0.2, 0.1, 0.0]]), nodes)

dofmap#

fenicsx_compat.dofmap(mesh) -> numpy.ndarray

The geometry dofmap: the node indices of each cell, shape (num_cells, num_nodes_per_cell).

DOLFINx

Native

0.10

mesh.geometry.dofmap

0.11, main

mesh.geometry.dofmaps[0]. mesh.geometry.dofmap still works but emits a DeprecationWarning.

cell_nodes = mesh.geometry.x[fenicsx_compat.dofmap(mesh)]  # (num_cells, num_nodes_per_cell, 3)

meshtags_topology#

Added in version 0.2.0.

fenicsx_compat.meshtags_topology(tags) -> dolfinx.mesh.Topology

The topology a MeshTags is defined on, always as the Python dolfinx.mesh.Topology.

DOLFINx

tags.topology returns

Native Python topology

0.10, 0.11

the C++ topology

dolfinx.mesh.Topology(tags.topology)

main (DOLFINx PR #4350)

the Python topology

tags.topology

topology = fenicsx_compat.meshtags_topology(facet_tags)
cpp_topology = topology._cpp_object  # the C++ object, on every version

cell_permutation_info#

fenicsx_compat.cell_permutation_info(topology) -> numpy.ndarray  # uint32

Computes and returns the packed per-cell permutation info, ghost cells included, as used by dof transformations.

cell_info = fenicsx_compat.cell_permutation_info(mesh.topology)
# e.g. for V.element.Tt_inv_apply(data, cell_info, n)

Calling it is also the portable way to make sure the permutations are computed before handing the topology to code that needs them.

facet_permutations#

fenicsx_compat.facet_permutations(topology) -> numpy.ndarray  # uint8

The permutation of every facet of every cell, shape (num_cells, num_facets_per_cell), ghost cells included. These are the values FFCx kernels take as quadrature_permutation.

perms = fenicsx_compat.facet_permutations(mesh.topology)
perm = perms[cell, local_facet]

On main, an interval mesh gives an empty array, since points have no orientation.

create_facet_orientations#

Added in version 0.3.0.

fenicsx_compat.create_facet_orientations(topology) -> None

Computes the facet orientations that Raviart-Thomas and other contravariant Piola spaces need on a manifold. Call it on every rank, before creating the space.

DOLFINx

Native

0.10, 0.11

No equivalent, and none needed: such spaces are created without it. Does nothing.

main (DOLFINx PR #4625)

topology.create_facet_orientations(). Creating such a space on a manifold raises RuntimeError until it has been called.

submesh = dolfinx.mesh.create_submesh(mesh, 2, boundary_facets)[0]
fenicsx_compat.create_facet_orientations(submesh.topology)
V = dolfinx.fem.functionspace(submesh, ("RT", 1))

On main it raises ValueError for a topology whose dimension is not 2, as the native method does. Lagrange and Nédélec spaces do not need it.

transfer_meshtags_to_submesh#

fenicsx_compat.transfer_meshtags_to_submesh(entity_tag, submesh, cell_to_parent, vertex_to_parent)
    -> dolfinx.mesh.MeshTags

Transfers tags on a parent mesh to a submesh created with dolfinx.mesh.create_submesh().

The two maps swapped places between 0.11 and main while keeping their names, so a positional call that is right on one version passes the maps the wrong way round on the other. That does not raise. The wrapper forwards by keyword, and takes the maps in the order create_submesh returns them:

submesh, cell_map, vertex_map, _ = dolfinx.mesh.create_submesh(mesh, tdim, cells)
sub_tags = fenicsx_compat.transfer_meshtags_to_submesh(cell_tags, submesh, cell_map, vertex_map)

If you call DOLFINx directly, pass both maps by keyword: cell_to_parent=cell_map, vertex_to_parent=vertex_map.