Thanks @dokken, after interpolate we can view the output now. But I find the results from p1-iso-p2/p1 is not matching the results as p2/p1.
The first problem I had is that create_mesh doesn’t seem to work with iso element?
domain = basix.ufl.element(basix.ElementFamily.iso, "triangle", 1, shape=(2,))
x = [[0., 0.], [1., 0.], [0., 1.], [1., 1.]]
cells = cells = [[0, 3, 1], [0, 2, 3]]
msh = create_mesh(MPI.COMM_WORLD, cells, x, domain)
This will lead to error
munmap_chunk(): invalid pointer
[ca1ee4a86145:30195] *** Process received signal ***
[ca1ee4a86145:30195] Signal: Aborted (6)
[ca1ee4a86145:30195] Signal code: (-6)
[ca1ee4a86145:30195] [ 0] /usr/lib/x86_64-linux-gnu/libc.so.6(+0x42520)[0x7b457e13a520]
[ca1ee4a86145:30195] [ 1] /usr/lib/x86_64-linux-gnu/libc.so.6(pthread_kill+0x12c)[0x7b457e18e9fc]
[ca1ee4a86145:30195] [ 2] /usr/lib/x86_64-linux-gnu/libc.so.6(raise+0x16)[0x7b457e13a476]
[ca1ee4a86145:30195] [ 3] /usr/lib/x86_64-linux-gnu/libc.so.6(abort+0xd3)[0x7b457e1207f3]
[ca1ee4a86145:30195] [ 4] /usr/lib/x86_64-linux-gnu/libc.so.6(+0x89676)[0x7b457e181676]
[ca1ee4a86145:30195] [ 5] /usr/lib/x86_64-linux-gnu/libc.so.6(+0xa0cfc)[0x7b457e198cfc]
[ca1ee4a86145:30195] [ 6] /usr/lib/x86_64-linux-gnu/libc.so.6(+0xa0fdc)[0x7b457e198fdc]
[ca1ee4a86145:30195] [ 7] /usr/lib/x86_64-linux-gnu/libc.so.6(free+0xba)[0x7b457e19d49a]
[ca1ee4a86145:30195] [ 8] /usr/lib/x86_64-linux-gnu/libmpi.so.40(ompi_comm_free+0x273)[0x7b4570058ea3]
[ca1ee4a86145:30195] [ 9] /usr/lib/x86_64-linux-gnu/libmpi.so.40(PMPI_Comm_free+0x76)[0x7b4570097246]
[ca1ee4a86145:30195] [10] /usr/lib/x86_64-linux-gnu/libdolfinx_real.so.0.9(_ZN7dolfinx3MPI4CommD2Ev+0x19)[0x7b455d71fca9]
[ca1ee4a86145:30195] [11] /usr/lib/petsc/lib/python3/dist-packages/dolfinx/cpp.cpython-310-x86_64-linux-gnu.so(+0x215a47)[0x7b455da67a47]
[ca1ee4a86145:30195] [12] /usr/lib/petsc/lib/python3/dist-packages/dolfinx/cpp.cpython-310-x86_64-linux-gnu.so(+0x25e4b2)[0x7b455dab04b2]
[ca1ee4a86145:30195] [13] /usr/lib/petsc/lib/python3/dist-packages/dolfinx/cpp.cpython-310-x86_64-linux-gnu.so(+0x29f8f9)[0x7b455daf18f9]
[ca1ee4a86145:30195] [14] python3(+0x169b87)[0x5d02e7575b87]
[ca1ee4a86145:30195] [15] python3(+0x1a2751)[0x5d02e75ae751]
[ca1ee4a86145:30195] [16] python3(+0x169bc7)[0x5d02e7575bc7]
[ca1ee4a86145:30195] [17] python3(+0x1a2751)[0x5d02e75ae751]
[ca1ee4a86145:30195] [18] python3(+0x15b797)[0x5d02e7567797]
[ca1ee4a86145:30195] [19] python3(_PyEval_EvalFrameDefault+0x1be5)[0x5d02e7582eb5]
[ca1ee4a86145:30195] [20] python3(+0x25ae56)[0x5d02e7666e56]
[ca1ee4a86145:30195] [21] python3(PyEval_EvalCode+0x86)[0x5d02e7666d26]
[ca1ee4a86145:30195] [22] python3(+0x281ae8)[0x5d02e768dae8]
[ca1ee4a86145:30195] [23] python3(+0x27c2ef)[0x5d02e76882ef]
[ca1ee4a86145:30195] [24] python3(+0x281885)[0x5d02e768d885]
[ca1ee4a86145:30195] [25] python3(_PyRun_SimpleFileObject+0x1a8)[0x5d02e768ce68]
[ca1ee4a86145:30195] [26] python3(_PyRun_AnyFileObject+0x47)[0x5d02e768cb47]
[ca1ee4a86145:30195] [27] python3(Py_RunMain+0x2be)[0x5d02e768102e]
[ca1ee4a86145:30195] [28] python3(Py_BytesMain+0x2d)[0x5d02e765ad6d]
[ca1ee4a86145:30195] [29] /usr/lib/x86_64-linux-gnu/libc.so.6(+0x29d90)[0x7b457e121d90]
[ca1ee4a86145:30195] *** End of error message ***
Aborted (core dumped)
Then I also can’t get good results with p1-iso-p2 element, while change the element to P2 will work out just fine. I attach my complete code below for your review.
import time
import pyvista
import numpy as np
import ufl
import basix
import dolfinx
import dolfinx.fem.petsc
from dolfinx.fem.petsc import assemble_matrix_block, assemble_vector_block
from dolfinx import cpp as _cpp
from dolfinx import fem
from dolfinx import plot
from dolfinx.fem import (Constant, Function, functionspace, dirichletbc,
extract_function_spaces, form, Expression,
locate_dofs_geometrical, locate_dofs_topological,
create_interpolation_data, assemble_scalar)
from dolfinx.io import XDMFFile
from dolfinx.mesh import (CellType, GhostMode, create_rectangle, locate_entities,
locate_entities_boundary, meshtags, DiagonalType, refine,
create_mesh)
from dolfinx import geometry
from ufl import div, dx, grad, inner, Measure
from basix.ufl import element, mixed_element
from mpi4py import MPI
from petsc4py import PETSc
domain = basix.ufl.element("Lagrange", "triangle", 2, shape=(2,))
# domain = basix.ufl.element(basix.ElementFamily.iso, "triangle", 1, shape=(2,))
# x = [[0., 0.], [1., 0.], [0., 1.], [1., 1.]]
# cells = cells = [[0, 3, 1], [0, 2, 3]]
# msh = create_mesh(MPI.COMM_WORLD, cells, x, domain)
# for i in range(2):
# msh.topology.create_entities(1)
# msh, _, _ = refine(msh)
msh = create_rectangle(MPI.COMM_WORLD,
[np.array([0, 0]), np.array([1., 1.])],
[8, 8],
CellType.triangle, ghost_mode=GhostMode.none,
diagonal=DiagonalType.left_right)
# P2 = element(basix.ElementFamily.iso, msh.topology.cell_name(), 1, shape=(2,))
P2 = element("Lagrange", msh.topology.cell_name(), 2, shape=(2,))
P1 = element("Lagrange", msh.topology.cell_name(), 1)
V, Q = functionspace(msh, P2), functionspace(msh, P1)
(u, p) = ufl.TrialFunction(V), ufl.TrialFunction(Q)
(v, q) = ufl.TestFunction(V), ufl.TestFunction(Q)
f = Constant(msh, (PETSc.ScalarType(0.0), PETSc.ScalarType(0.0)))
a = form([[inner(grad(u), grad(v)) * dx, inner(p, div(v)) * dx], [inner(div(u), q) * dx, Constant(msh, PETSc.ScalarType(0))*p*q*dx]])
L = form([inner(f, v) * dx, inner(Constant(msh, PETSc.ScalarType(0)), q) * dx]) # type: ignore
#-----------------SET THE BOUNDARY CONDITIONS FOR THE PROBLEM----------------------------------------------
def inlet_profile_expression(x):
return np.stack((x[0]*0, x[0]**2-x[0]))
# Function to mark x = 0, x = 1 and y = 0
def noslip_boundary(x):
return np.isclose(x[0], 0.0) | np.isclose(x[0], 1.0)
# Function to mark the lid (y = 1)
def inlet(x):
return np.isclose(x[1], 1.0)
# +
# No-slip condition on boundaries where x = 0, x = 1, and y = 0
noslip = np.zeros(msh.geometry.dim, dtype=PETSc.ScalarType) # type: ignore
facets = locate_entities_boundary(msh, 1, noslip_boundary)
bc0 = dirichletbc(noslip, locate_dofs_topological(V, 1, facets), V)
# Driving (lid) velocity condition on top boundary (y = 1)
inlet_profile = Function(V)
inlet_profile.interpolate(inlet_profile_expression)
facets = locate_entities_boundary(msh, 1, inlet)
bc1 = dirichletbc(inlet_profile, locate_dofs_topological(V, 1, facets))
bcs = [bc0, bc1]
# Assemble LHS matrix and RHS vector
a,L = form(a),form(L)
A = assemble_matrix_block(a, bcs=bcs)
A.assemble()
b = assemble_vector_block(L, a, bcs=bcs)
# Create a solver
ksp = PETSc.KSP().create(msh.comm)
ksp.setOperators(A)
ksp.setType("preonly")
# Set the solver type to MUMPS (LU solver) and configure MUMPS to
# handle pressure nullspace
pc = ksp.getPC()
pc.setType("lu")
pc.setFactorSolverType("mumps")
pc.setFactorSetUpSolverType()
pc.getFactorMatrix().setMumpsIcntl(icntl=24, ival=1) # For pressure nullspace
pc.getFactorMatrix().setMumpsIcntl(icntl=25, ival=0) # For pressure nullspace
# Create a block vector (x) to store the full solution, and solve
x = A.createVecLeft()
ksp.solve(b, x)
# Create Functions and scatter x solution
u, p = Function(V), Function(Q)
offset = V.dofmap.index_map.size_local * V.dofmap.index_map_bs
u.x.array[:offset] = x.array_r[:offset]
p.x.array[: (len(x.array_r) - offset)] = x.array_r[offset:]
# P2iso = element(basix.ElementFamily.iso, msh.topology.cell_name(), 1, shape=(2,))
# P2lag = element("Lagrange", "triangle", 1, shape=(2,))
# Vlag = functionspace(msh, P2lag)
# Viso = functionspace(msh, P2iso)
# cells_lag_map = Vlag.mesh.topology.index_map(Vlag.mesh.topology.dim)
# num_cells_lag = cells_lag_map.size_local + cells_lag_map.num_ghosts
# cells_lag = np.arange(num_cells_lag, dtype=np.int32)
# ulag = Function(Vlag)
# interpolation_data = create_interpolation_data(Vlag, Viso, cells_lag)
# ulag.interpolate_nonmatching(u, cells_lag, interpolation_data=interpolation_data)
# ulag.x.scatter_forward()
# pyvista.start_xvfb()
# topology, cell_types, geometry = plot.vtk_mesh(Vlag)
# values = np.zeros((geometry.shape[0], 3), dtype=np.float64)
# values[:, :len(u)] = u.x.array.real[0:geometry.shape[0]*2].reshape((geometry.shape[0], len(u)))
pyvista.start_xvfb()
topology, cell_types, geometry = plot.vtk_mesh(V)
values = np.zeros((geometry.shape[0], 3), dtype=np.float64)
values[:, :len(u)] = u.x.array.real[0:geometry.shape[0]*2].reshape((geometry.shape[0], len(u)))
# Create a point cloud of glyphs
function_grid = pyvista.UnstructuredGrid(topology, cell_types, geometry)
function_grid["u"] = values
glyphs = function_grid.glyph(orient="u", factor=0.5)
# Create a pyvista-grid for the mesh
msh.topology.create_connectivity(msh.topology.dim, msh.topology.dim)
# Create plotter
plotter = pyvista.Plotter(off_screen=True)
plotter.add_mesh(function_grid, style="wireframe", color="k")
plotter.add_mesh(glyphs)
plotter.view_xy()
fig_as_array = plotter.screenshot("glyphs.png")
Results from iso
Results from P2