# How to use MeshFunction in FEniCS (dolfin)?

I'm a beginner user of FEniCS and still struggling with some of the basics. Specifically,
I have some issues doing the tutorials in the Langtangen-Logg book Solving PDEs in Python - The FEniCS Tutorial Volume I. I think some of the problems are due to the different versions of the book and my installation (2019.1.0).

One of the issues is the use of the MeshFunction or CellFunction, FacetFunction, etc.

The example (4.3.2 on page 90) says:

materials = CellFunction(’size_t’, mesh)


which doesn't work for me. After some research I found out that CellFunction is deprecated since 2017.2.0:
Deprecate VertexFunction, EdgeFunction, FaceFunction, FacetFunction, CellFunction; use MeshFunction instead

I got the example to work with some trial and error (at least it looks like it's working):

materials = MeshFunction('size_t', mesh, 2)


But I do not really understand how and why. Especially after trying the next example that uses FacetFunction.

The 2017.2.0 doc doesn't say much about how to use MeshFunction. The descripton for the dim (unsigned int) argument says:
The topological dimension of the MeshFunction. Optional.

The description for CellFunction is just:
Create MeshFunction of topological codimension 0 on given mesh.
For FacetFunction:
Create MeshFunction of topological codimension 1 on given mesh.

It doesn't work with materials = MeshFunction('size_t', mesh, 0). I figured that the codimension 0 might mean to use 0 for the dim argument in the case of "CellFunction".

Therefore, my questions are:

1. Is the "codimension" referring to the dim argument?
2. What does "topological dimension" and "topological codimension" mean in this context?
3. If I should use MeshFunction instead of all those other functions mentioned above, how does using MeshFunction for cells differ from using it for facets, etc.

PS: I am aware of the question Fenics: Meshfunction usage, but it doesn't really answer my question

• You might get (or already find!) better answers at fenicsproject.discourse.group, but you need to give the (no longer optional) topological dimension using MeshFunction('size_t',mesh,mesh.topology().dim()) (for cells in 2d, use mesh.topology().dim()-1 for facets and mesh.topology(),dim()-2 for vertices). This is described in this commented demo. Always make sure that what you're looking at (even if it's a book) matches the version you are using (which you didn't specify). May 14 '19 at 15:43
• Thank you! I added the version in the question (2019.1.0). I'd love to do a tutorial that matches my installation, but the mentioned book looked like the best recent tutorial I could find. And it's also recommended on the FEniCS website. Installing and learning an old version didn't seem like a good way either, that's why I try to adjust the examples May 14 '19 at 16:02
• The FEniCS website explicitly warns that the examples in the tutorial are obsolete :) May 14 '19 at 16:06

The different specialized VertexFunction, EdgeFunction, FaceFunction, FacetFunction, CellFunction have indeed been deprecated and (at least) as of version 2018.2 removed. Instead, they have been merged into a general purpose MeshFunction which takes the kind of mesh object they're defined on as a (mandatory) parameter called the "topological dimension".

To understand what to put there, it may be helpful to stress the differences between geometric objects (points, lines, polygons, polyhedra) and topological objects (vertices, edges, facets, cells) -- while the former have the same dimension (basically by definition) no matter what the definition of the ambient space is (the "n" in "nD"), the latter do not, since they depend on the role they play in forming the mesh. These are instead distinguished by they codimension, which is "n minus geometric dimension" (how far they are from "full space"):

• cells have (by definition) codimension 0
• facets have (by definition) codimension 1 (boundaries of cells)
• edges have (by definition) codimension n-1
• vertices have (by definition) codimension n (boundaries of edges)

For example, in 1D a line (geometric dimension 1) is a cell (codimension 0=1-1), while in 2D it's a facet (codimension 1=2-1) (These can overlap: In 2D, edges and facets are the same; in 1D, facets and vertices are (and edges make no sense).)

Back to FEniCS: As the above tried to illustrate, mesh objects are described by their codimension; nevertheless, MeshFunction takes the actual (geometric) dimension, which by simple arithmetic is "n minus codimension". To write this in a dimension-independent way, you can make use of the function mesh.topology().dim() So for example, to mark

• cells, use MeshFunction('size_t',mesh,mesh.topology().dim())
• facets, use MeshFunction('size_t',mesh,mesh.topology().dim()-1)
• edges, use MeshFunction('size_t',mesh,1)
• vertices, use MeshFunction('size_t',mesh,0)

DISCLAIMER: This is valid for versions 2018.1 to 2019.1.

If you're using the latest version of FEniCS, the meshing tools are deprecated as you've noticed. These tools are now under mshr module. You can install it via terminal: conda install -c conda-forge mshr

Additionally, if you'd like to convert meshes, the dolfin-convert became deprecated as well. The functions are now bundled in meshio module. Similarly: conda install -c kayarre meshio

The usage in both cases should be the similar as described in older dolfin/FEniCS documentation.

• I'm using 2019.1.0, MeshFunction still seems to work even without mshr. However, I have mshr installed, but I do not understand how to make the above mentioned example work with or without mshr. The mshr doc doesn't seem to have a MeshFunction`. Are there docs or tutorials that explain how the "old" way translates to how to do it in the newer versions? May 14 '19 at 15:47
• Feel free to ask those questions on Discourse Group. fenicsproject.discourse.group By all means I'm trying to avoid using mshr for that particular reason and I'm importing mesh created external tool. May 14 '19 at 16:23