# Copyright (C) 2017-2020 Chris N. Richardson and Garth N. Wells
#
# This file is part of DOLFINx (https://www.fenicsproject.org)
#
# SPDX-License-Identifier: LGPL-3.0-or-later
"""Creation, refining and marking of meshes"""
import types
import numpy
import ufl
from dolfinx import cpp
from dolfinx.cpp.mesh import create_meshtags
__all__ = [
"locate_entities", "locate_entities_boundary", "refine", "create_mesh", "create_meshtags", "MeshTags"
]
[docs]def locate_entities(mesh: cpp.mesh.Mesh,
dim: int,
marker: types.FunctionType):
"""Compute list of mesh entities satisfying a geometric marking function.
Parameters
----------
mesh
The mesh
dim
The topological dimension of the mesh entities to consider
marker
A function that takes an array of points `x` with shape
``(gdim, num_points)`` and returns an array of booleans of length
``num_points``, evaluating to `True` for entities to be located.
Returns
-------
numpy.ndarray
Indices (local to the process) of marked mesh entities.
"""
return cpp.mesh.locate_entities(mesh, dim, marker)
[docs]def locate_entities_boundary(mesh: cpp.mesh.Mesh,
dim: int,
marker: types.FunctionType):
"""Compute list of mesh entities that are attached to an owned boundary facet
and satisfy a geometric marking function.
For vertices and edges, in parallel this function will not necessarily
mark all entities that are on the exterior boundary. For example, it is
possible for a process to have a vertex that lies on the boundary without
any of the attached facets being a boundary facet. When used to find
degrees-of-freedom, e.g. using fem.locate_dofs_topological, the function
that uses the data returned by this function must typically perform some
parallel communication.
Parameters
----------
mesh
The mesh
dim
The topological dimension of the mesh entities to
consider
marker
A function that takes an array of points `x` with shape
``(gdim, num_points)`` and returns an array of booleans of length
``num_points``, evaluating to `True` for entities to be located.
Returns
-------
numpy.ndarray
Indices (local to the process) of marked mesh entities.
"""
return cpp.mesh.locate_entities_boundary(mesh, dim, marker)
_uflcell_to_dolfinxcell = {
"interval": cpp.mesh.CellType.interval,
"triangle": cpp.mesh.CellType.triangle,
"quadrilateral": cpp.mesh.CellType.quadrilateral,
"tetrahedron": cpp.mesh.CellType.tetrahedron,
"hexahedron": cpp.mesh.CellType.hexahedron
}
_meshtags_types = {
numpy.int8: cpp.mesh.MeshTags_int8,
numpy.int32: cpp.mesh.MeshTags_int32,
numpy.int64: cpp.mesh.MeshTags_int64,
numpy.double: cpp.mesh.MeshTags_double
}
[docs]def refine(mesh, cell_markers=None, redistribute=True):
"""Refine a mesh"""
if cell_markers is None:
mesh_refined = cpp.refinement.refine(mesh, redistribute)
else:
mesh_refined = cpp.refinement.refine(mesh, cell_markers, redistribute)
coordinate_element = mesh._ufl_domain.ufl_coordinate_element()
domain = ufl.Mesh(coordinate_element)
domain._ufl_cargo = mesh_refined
mesh_refined._ufl_domain = domain
return mesh_refined
[docs]def create_mesh(comm, cells, x, domain,
ghost_mode=cpp.mesh.GhostMode.shared_facet,
partitioner=cpp.mesh.partition_cells_graph):
"""Create a mesh from topology and geometry data"""
ufl_element = domain.ufl_coordinate_element()
cell_shape = ufl_element.cell().cellname()
cell_degree = ufl_element.degree()
cmap = cpp.fem.CoordinateElement(_uflcell_to_dolfinxcell[cell_shape], cell_degree)
try:
mesh = cpp.mesh.create_mesh(comm, cells, cmap, x, ghost_mode, partitioner)
except TypeError:
mesh = cpp.mesh.create_mesh(comm, cpp.graph.AdjacencyList_int64(numpy.cast['int64'](cells)),
cmap, x, ghost_mode, partitioner)
# Attach UFL data (used when passing a mesh into UFL functions)
domain._ufl_cargo = mesh
mesh._ufl_domain = domain
return mesh
# Functions to extend cpp.mesh.Mesh with
def ufl_cell(self):
return ufl.Cell(self.topology.cell_name(), geometric_dimension=self.geometry.dim)
def ufl_domain(self):
"""Return the ufl domain corresponding to the mesh."""
return self._ufl_domain
# Extend cpp.mesh.Mesh class, and clean-up
cpp.mesh.Mesh.ufl_cell = ufl_cell
cpp.mesh.Mesh.ufl_domain = ufl_domain
del ufl_cell
del ufl_domain