Meshing and Visualization

45 minutes intermediate

  Lesson Objectives

  Learn about external mesh generators that can be used with MFEM.
  Learn about MFEM's internal meshing tools.
  Learn about external visualization tools that can be used with MFEM.


Please complete the   Getting Started and Finite Element Basics pages before this lesson.

  Importing meshes from Gmsh and Cubit

In this section we demonstrate the common steps necessary for generating high-quality meshes in Gmsh and Cubit and how to use them in finite element simulations with MFEM.

Gmsh is an open-source, freely available mesh generation tool with built-in computer-aided design (CAD) functionality and a postprocessor. The input to Gmsh can be a simple text file that provides a description of the geometry of the finite element model. The geometry can be generated using the Gmsh graphical user interface (GUI), simple text editors such as Vi/Vim/Emacs, or using more sophisticated CAD tools such as SolidWorks or Autocad. CAD models in IGES or STEP formats can be imported by the CAD engine of Gmsh, meshed, and prepared as inputs to the MFEM examples. Here, however, we focus on simpler examples showing the process of generating meshes suitable for MFEM and not on the actual geometry.

Many examples together with documentation on the input syntax can be found at the Gmsh website. Users familiar with Gmsh can skip the first steps and download already prepared geometries for meshing. If Gmsh is not installed on your local machine, please download it and follow the installation instructions.

We will start with the definitions of a cube with edge length L=1 and two cylinders with a radius L/10 and heights equal to L. The following snippet defines these objects:


Mesh.Algorithm = 6;
Mesh.CharacteristicLengthMin = 0.1;
Mesh.CharacteristicLengthMax = 0.1;


Box(1) = {0,0,0,L,L,L};

Cylinder(2) = {L/8, 0.0, L/4, 0, L, 0, Rc , 2*Pi};
Cylinder(3) = {4*L/8, 0.0, L/4, 0, L, 0, Rc , 2*Pi};

Here is a screenshot of the GUI of Gmsh with the generated objects:

The first line in the Gmsh input file defines the geometric engine. Here it is assumed that Gmsh is compiled with CAD support. Such precompiled binaries for Windows, Mac, and Linux can be downloaded from the Gmsh website. The next three lines define the mesh algorithm, which will be used later for generating the mesh and the associated characteristic length scale. Finer or coarser meshes can be obtained by adjusting these numbers. The following line defines a parameter L which is utilized in the definition of the cube. A parameter R defines the radius of the base of the two cylinders. The final geometry, which will be used for simulations, is obtained by subtracting the two cylinders from the cube as:

BooleanDifference(50) = { Volume{1}; Delete; }{ Volume{2,3}; Delete; };

Gmsh uses the obtained geometry for generating the mesh. However, without additional specifications, we cannot impose boundary conditions without any attributes assigned to the boundaries. Different attributes can be assigned to the volumetric part of the mesh for using different material coefficients within the domain. Here, however, we use only a single attribute, as the first example uses only a single diffusion coefficient.

Physical Volume(1) = {50};
Physical Surface(1) = {1,6,8};

Mesh.MshFileVersion = 2.2;

The first line from the above snippet defines physical volume 1 to coincide with the geometry volume 50, which is the final volume obtained by the Boolean operation. The second line defines physical surface 1 to include geometric surfaces {1,6,8}. Finally, the last line specifies the file format. Note that MFEM can only read ASCII Gmsh format version 2.2.

The generated mesh is shown in the figures above. Careful inspection reveals that the cylindrical surface is not represented well by the linear elements. We can improve the representation by refining the mesh. We encourage you to play with the mesh and to generate finer discretizations for the simulations.

You can download the Gmsh input file here and the resulting mesh file here. For users without access to the Gmsh GUI, a mesh can be generated in your local terminal with the following command:

gmsh -3 cross_heat.geo

To run simulations with the generated mesh, drag-and-drop the mesh file from your computer to the AWS browser window in the MFEM examples directory:

To run Example 1 with the newly prepared mesh, be sure you are in the examples directory and then run the following command:

mpirun -np 24 ./ex1p -m cross_heat.msh -no-vis

The solution of the diffusion equation for the generated mesh is shown in the following two pictures. The figures are generated with ParaView, and the process of visualization is explained at the end of this tutorial session.

If we want to enforce Dirichlet boundary conditions different than zero on some other surface, we must export it as a physical surface. For example, to enforce value one on the other cylindrical surface, add the following line to the cross_heat.geo file:

Physical Surface(2) = {7};

The line should be inserted in any place after the definition of geometrical surface 7, e.g., after the boolean operation defining the final geometry.

If we run ex1.cpp without modifications, a zero value will be assigned to the newly defined surface. Thus, in order to set it to one, modify section 10 in ex1p.cpp:

   // 10. Define the solution vector x as a parallel finite element grid
   //     function corresponding to fespace. Initialize x with initial guess of
   //     zero, which satisfies the boundary conditions.
   ParGridFunction x(&fespace);
   x = 0.0;
      Array<int> ess_bdr(pmesh.bdr_attributes.Max());
      ess_bdr = 0;
      ess_bdr[1] = 1;
      ConstantCoefficient zero(0.0);
      Coefficient* coeff[1];

In the above snippet, we project coefficient one on the degrees of freedom associated with physical surface 2 (the indexing starts at zero). Executing the modified code with the newly created mesh will result in the following solution:

The results can be seen in the GLVis windows as well. However, the users will see only the defined physical surfaces (1,2) and the boundaries between the parallel partitions. Any 2D cuts will work as usual.

MFEM can import meshes saved in Exodus II format generated with Cubit. However, this feature requires compilation of the library with HDF5, NetCDF, and Exodus, which is not available in the AWS tutorial image.

  MFEM's meshing tools

MFEM provides many tools, routines, and examples for mesh manipulation. The miniapp examples illustrate a large part of the MFEM functionality in the miniapps/meshing subdirectory. Below we provide more details about only two of these miniapps. However, users are encouraged to also explore the other meshing miniapps.

  Mesh Explorer

The mesh explorer miniapp is a handy tool to examine, visualize and manipulate a given mesh. Users have to compile it in the miniapps/meshing subdirectory:

cd ~/mfem/miniapps/meshing
make mesh-explorer

Once compiled, it can be executed in the same directory by typing in the terminal


Before executing it, users should ensure that the GLVis window is open and connected to the AWS machine. Once started, many options will appear in the terminal window. An example screenshot of provided below

By pressing the corresponding keys, a number of operations can be performed on the input mesh files, including:

For example, selecting v in the prompt and pressing enter will display the default mesh of a hex-meshed beam in the GLVis window. To operate on a different mesh, users should exit the miniapp with q and start it again with the following line

./mesh-explorer -m new_mesh_file.msh

Here new_mesh_file.msh is the mesh file selected by the user. The input mesh can be in any format supported by MFEM. In addition, the miniapp can save the loaded mesh in native MFEM and VTK formats.


Shaper is a miniapp that performs multiple levels of adaptive mesh refinement to resolve the interfaces between different "materials" in the mesh, as specified by a given material function. It can be used as a simple initial mesh generator, for example in the case when the interface is too complex to describe without local refinement. Both conforming and non-conforming refinements are supported.

To experiment with it, go to the miniapps/meshing subdirectory and type:

cd ~/mfem/miniapps/meshing
make shaper

The result of the execution with five levels of refinement and default setting can be seen in the following screenshot.

Users can specify different material distributions by modifying the function

int material(Vector &x, Vector &xmin, Vector &xmax)

in the begging of shaper.cpp.

The current function returns integer values of 1 if a point is located within a simple annulus/shell with a relative inner radius of 0.4 and outer radius of 0.6 and 2 otherwise. The coordinates of a point within the mesh are mapped to values between minus one and one.

Users are encouraged to modify the material distribution function and use different meshes as input. The refinement level is controlled in the terminal by pressing y for further refinement or n for completing the run. The resulting mesh is written in a file shaper.mesh. Once the mesh is written, users can use it as an input to other examples or miniapps.


See also the related Mandel and Mondrian miniapps in the miniapps/toys subdirectory.

  Visualizing results in ParaView and VisIt

To save the simulation results from the parallel version of Example 1 (ex1p.cpp) in ParaView format, add the following lines just before step 17 in the file.

   ParaViewDataCollection *pd = NULL;
   pd = new ParaViewDataCollection("Example1P", &pmesh);
   pd->RegisterField("solution", &x);
   delete pd;

The first line defines a ParaViewDataCollection for saving data in ParaView data format. The following two lines define the name of the data collection and the prefix path, which is set to ParaView. Thus, the data set will be written in the directory ParaView relative to the current execution path. The following line registers the ParGridFunction x in the data collection. The remaining lines set different parameters for the format and the data set, and finally, the set is saved and deleted. See MFEM documentation for more detailed information about ParaView.

Compile and execute the modified example.

To download the results saved in ParaView format to your local machine, compress and gather all files in a single archive with the following command:

tar cvfz paraview.tgz ParaView/

which will generate the file paraview.tgz in the current directory.

Download the file to your local machine by dragging it from the Explorer window:

Then go to the download location and extract the archive with

tar vxfz paraview.tgz ParaView/

The above assumes a UNIX type of environment. Windows users could use the GUI or WSL/WSL2 engines.

ParaView can be freely downloaded both as a source code or precompiled binaries. The precompiled binaries are available for Linux, macOS, and Windows. Please follow the instructions for the corresponding operating system for installation instructions.

To visualize the downloaded simulation data, run ParaView and open the file Example1P.pvd in the ParaView/Example1P directory, where the path is relative to the directory where the archive was downloaded. Next, click on the Apply button and select Solution in the drop-down menu in the second row of buttons. The geometry, together with the solution, can be rotated on the screen by holding and dragging the mouse.

Replacing ParaviewDataCollection with VisItDataCollection allows you to write data in VisIt data format. VisIt can be freely downloaded and installed on Linux, macOS, and Windows and provides another alternative to ParaView. The steps for downloading and the simulation data are the same as the steps outlined above for ParaView.


Ask for help in the tutorial Slack channel.

  Next Steps

Depending on your interests pick one of the following lessons:

Back to the MFEM tutorial page