I am solving the poisson problem using quadrilateral elements defined using the gmsh python library.
The problem is: the solution does exactly like if i had used triangles. Is there an error in the code, where I define the mesh?
import gmsh
from dolfinx.io import gmshio
from dolfinx.fem.petsc import LinearProblem
from mpi4py import MPI
import numpy as np
import ufl
from dolfinx import fem, io, mesh, plot
from ufl import ds, dx, grad, inner
import pyvista
# necessary in python
gmsh.initialize()
gmsh.clear()
gdim = 2
# rectangle
lc = 0.1
p1 = gmsh.model.geo.addPoint(0, 0, 0, lc)
p2 = gmsh.model.geo.addPoint(1, 0, 0, lc)
p3 = gmsh.model.geo.addPoint(1, 1, 0, lc)
p4 = gmsh.model.geo.addPoint(0, 1, 0, lc)
l1 = gmsh.model.geo.addLine(p1, p2)
l2 = gmsh.model.geo.addLine(p2, p3)
l3 = gmsh.model.geo.addLine(p3, p4)
l4 = gmsh.model.geo.addLine(p4, p1)
cl = gmsh.model.geo.addCurveLoop([l1, l2, l3, l4])
ps = gmsh.model.geo.addPlaneSurface([cl])
gmsh.model.geo.synchronize()
gmsh.model.addPhysicalGroup(gdim, [ps], tag=1)
# element number in one dimension
elem_nr = 3
# mesh
gmsh.model.geo.mesh.setTransfiniteCurve(1, elem_nr+1)
gmsh.model.geo.mesh.setTransfiniteCurve(2, elem_nr+1)
gmsh.model.geo.mesh.setTransfiniteCurve(3, elem_nr+1)
gmsh.model.geo.mesh.setTransfiniteCurve(4, elem_nr+1)
gmsh.model.geo.mesh.setTransfiniteSurface(1, "Alternate", [1, 2, 3, 4])#"Alternate" / "Right" / "Left"
gmsh.model.geo.synchronize()
gmsh.model.mesh.setRecombine(2, ps) # quad / tet
# gmsh.model.mesh.setTransfiniteAutomatic()
gmsh.model.mesh.generate(gdim)
# interface to dolfinx
msh, cell_markers, facet_markers = gmshio.model_to_mesh(gmsh.model,
MPI.COMM_WORLD,
rank=0,
gdim=gdim)
V = fem.functionspace(msh, ("Lagrange", 1))
# BC
facets = mesh.locate_entities_boundary(msh, dim=1,
marker=lambda x: np.logical_or.reduce((
np.isclose(x[0], 0.0),
np.isclose(x[0], 1.0),
np.isclose(x[1], 0.0),
np.isclose(x[1], 1.0))))
dofs = fem.locate_dofs_topological(V=V, entity_dim=1, entities=facets)
bc = [fem.dirichletbc(0.0, dofs=dofs, V=V)]
# var problem
u = ufl.TrialFunction(V)
v = ufl.TestFunction(V)
x = ufl.SpatialCoordinate(msh)
f = 10
a = inner(grad(u), grad(v)) * dx
L = inner(f, v) * dx
problem = LinearProblem(a, L, bcs=bc, petsc_options={"ksp_type": "preonly", "pc_type": "lu"})
uh = problem.solve()
# plots
cells, types, x = plot.vtk_mesh(V)
grid = pyvista.UnstructuredGrid(cells, types, x)
grid.point_data["u"] = uh.x.array.real
grid.set_active_scalars("u")
plotter = pyvista.Plotter()
plotter.add_mesh(grid, show_edges=True)
warped = grid.warp_by_scalar()
plotter.add_mesh(warped)
plotter.show()
Here is a picture from above:
…and below:
By the way: the line
gmsh.model.geo.mesh.setTransfiniteSurface(1, "Alternate", [1, 2, 3, 4])
seems to be necessary to get a structured mesh, but the argument “Alternative” does not do anything, as we have quadrilaterals, and no triangles.