2D Quadrilateral Mesh (Gmsh, Dolfin)

I currently have code working for reading of gmsh with dolfin using the auto-generated triangular mesh that gmsh initializes. I would like to work in a quadrilaterally discretized space, such as the following .geo file:

// Gmsh project created on Tue Dec 08 11:46:33 2020

nx=10;
ny=10;

// Lengths in x and y
Lx=1;
Ly=1;

Point(1) = {0, 0, 0,0.1};
Point(2) = {0, Ly, 0,0.1};
Point(3) = {Lx, Ly, 0,0.1};
Point(4) = {Lx, 0, 0,0.1};
Line(1) = {1, 4};
Line(2) = {4, 3};
Line(3) = {3, 2};
Line(4) = {2, 1};

// Define surfaces
Line Loop(1) = {4, 1, 2, 3};
Plane Surface(1) = {1};

// Transfinite lines and surfaces for structured mesh
Transfinite Curve {1, 3} = nx+1 Using Progression 1;
Transfinite Curve {4, 2} = ny+1 Using Progression 1;
Transfinite Surface {1};

// Recombine surfaces to create quadrilaterals
Recombine Surface {1};

Physical Surface(1) = {1};

The relevant read functionality in my python file is as follows:

os.system('dolfin-convert %s.msh %s.xml' % (file_name, file_name))
mesh = Mesh("%s.xml" % file_name)

where file_name is a string containing the name of the generated .msh file (ver 2.2). Here is the error I get:

*** Unable to find cells of supported type.
Traceback (most recent call last):
  File <path-to-file>, line 18, in <module>
    mesh = Mesh("%s.xml" % file_name)
RuntimeError:

This is mainly because the .xml file that is created is blank.

What is the best course of action going forward? I have looked at meshio, but I can’t seem to get the module to work with either the triangular or quadrilateral .msh files.

Thank you.

Quadrilateral meshes never had full support in dolfin, but has been added in DOLFINx
See for instance: dolfinx/demo_gmsh.py at main · FEniCS/dolfinx · GitHub (which uses the GMSH python API directly)
or
Defining subdomains for different materials — FEniCSx tutorial
which uses meshio to convert msh files to XDMF format

Here is what I have:

import meshio
import dolfinx.io

def create_mesh(mesh, cell_type, prune_z=False):
    cells = mesh.get_cells_type(cell_type)
    cell_data = mesh.get_cell_data("gmsh:physical", cell_type)
    out_mesh = meshio.Mesh(points=mesh.points, cells={
                           cell_type: cells}, cell_data={"name_to_read": [cell_data]})
    if prune_z:
        out_mesh.prune_z_0()
    return out_mesh

msh = meshio.read("%s.msh" % file_name)

quad_mesh = create_mesh(msh, "quad", prune_z=True)
meshio.write("mesh.xdmf", quad_mesh)

with dolfinx.io.XDMFFile(MPI.COMM_WORLD, "mesh.xdmf", "r") as xdmf:
    mesh = xdmf.read_mesh(name="Grid")

will this be suitable? Also, I am struggling to install DOLFINx, could you advise on how to do this when running a conda environmnet?

1 Like

Something like that should work.

As far as I can know, dolfinx has not been packaged for conda. However, it is easily accessible as a Docker image: Docker Hub

I’m running my .py files through a conda environment in WSL as it was the easiest way to get fenics running. I did try to install docker but it wouldn’t access the docker daemon.

I’m currently trying to install through Spack which appears to be doing something…

Spack should work (although it takes quite some time).
To address your docker issue, I would suggest having a look at: https://www.digitalocean.com/community/questions/how-to-fix-docker-got-permission-denied-while-trying-to-connect-to-the-docker-daemon-socket

Spack didn’t work as it didn’t have the 'unzip package that is necessary.

The good news is I have docker working now, the problem was the WSL version I was using. I’ve executed docker run dolfinx/dolfinx, is there anything else I need to do?

You need to install meshio and h5py in the image, which can be done with

export HDF5_MPI="ON"
export CC=mpicc
export HDF5_DIR="/usr/lib/x86_64-linux-gnu/hdf5/mpich/"
pip3 install --no-binary=h5py h5py meshio

I still have an error with the module not being found. The docker image is live:

docker ps
CONTAINER ID   IMAGE                    COMMAND       CREATED          STATUS          PORTS     NAMES
64e8e1fe9fe9   dolfinx/dolfinx:latest   "/bin/bash"   15 minutes ago   Up 15 minutes             adoring_shamir

and I have h5py installed in my conda environment:

Package         Version
--------------- -------------------
attrs           21.2.0
Automat         20.2.0
certifi         2021.5.30
constantly      15.1.0
construct       2.10.67
cycler          0.10.0
fenics-dijitso  2019.2.0.dev0
fenics-dolfin   2019.1.0
fenics-ffc      2019.1.0
fenics-ffcx     0.1.1.dev0
fenics-fiat     2019.2.0.dev0
fenics-ufl      2021.1.0
gmpy2           2.1.0b1
gmsh            4.8.4
h5py            3.2.1
hyperlink       21.0.0
idna            3.2
incremental     21.3.0
kiwisolver      1.3.1
matplotlib      3.4.2
meshio          4.4.5
mpi4py          3.0.3
mpmath          1.2.1
numpy           1.20.3
petsc4py        3.14.1
Pillow          8.2.0
pip             21.1.2
pkgconfig       1.5.2
ply             3.11
protobuf        3.17.1
pyasn1          0.4.8
pybind11        2.6.2
pybind11-global 2.6.2
pycryptodomex   3.10.1
pygmsh          7.1.9
pyparsing       2.4.7
pysmi           0.3.4
pysnmp          4.4.12
python-dateutil 2.8.1
PyYAML          5.4.1
scipy           1.6.3
setuptools      49.6.0.post20210108
six             1.16.0
slepc4py        3.14.0
spack           0.5.2
sympy           1.8
tensor          0.3.6
Twisted         21.2.0
wheel           0.36.2
zope.interface  5.4.0

To me your pip3 list does not seem to be the one from the docker image, as it does not have any of the appropriate packages.
You should run docker in interactive mode as:
docker run -ti -v "$(pwd)":/root/shared -w /root/shared dolfinx/dolfinx.
This will launch an interactive session in a terminal with dolfinx.

When doing this and listing pip the modules are there, but I am unable to run my python file in the session. I go to the directory, start interactive mode, and python <file-name> outputs:
bash: python: command not found

Is it possible because I am running this from a conda environment?

You need to use python3 as python usually refers to python2.7, which has reached end of life

No problem. It looks like the Dockerfile doesn’t contain the meshio package. Should I add it to the docker file and make a new build for it to be included?

You can either install it with pip (as shown above) or create your own Dockerfile with the commands to install it

Thank you, I have installed with pip. When putting the generated mesh into paraview it looks like it has been converted properly, although I get this error when running;

Traceback (most recent call last):
  File "field_gen.py", line 45, in <module>
    V = dolfinx.FunctionSpace(mesh, "Lagrange", 1)
  File "/usr/local/dolfinx-real/lib/python3.8/dist-packages/dolfinx/fem/function.py", line 370, in __init__
    assert mesh is None
AssertionError

Sorry for the many questions, I am new to using Fenics as you can probably tell!

You need to provide a minimal running code example that reproduces the error, as there is no way of telling what you have done wrong by just looking at the error message. I would strongly suggest you to read through my tutorial:The FEniCSx tutorial — FEniCSx tutorial

No problem, thank you for your help and your time