I have a rectangular prism like in the image below where I know the coordinates of the vertices.
I want to discretize the lateral faces of the prism into an unstructured surface mesh using quadrilateral elements with a certain objective side length. More precisely, I am not interested in saving the mesh to a file, but I want a list representing the elements of the mesh and including a reference to the nodes composing each element (both in terms of id and coordinates). Is there a python library that can do this?
For a perfect rectangular prism like the one in the image above, it is fairly simple to obtain a structured surface mesh just by playing with the coordinates and numpy.linspace
. However, I want to be able to mesh a prism with some taper or with different bases. In those cases, a structured mesh might lead to very skewed elements, while I would like the elements to be as close as possible to a square with side equal to the objective length.
Ideally, the python script would start with the definition of the coordinates of the vertices and of the faces that have to be meshed:
import numpy as np
# Geometric properties
aspect_ratio = 9.
c = 1e3 # [mm]
b = aspect_ratio*c
non_dimensional_height = 0.1
h = c*non_dimensional_height # [mm]
non_dimensional_thickness = 0.001
t = c*non_dimensional_thickness # [mm]
# Objective length of the side of the quadrilateral elements
side_length = 10 # [mm]
# Define points coordinates
points_xyz = np.array([(0., 0., h/2), # 0 -> A
(c, 0., h/2), # 1 -> B
(0., 0., -h/2), # 2 -> C
(c, 0., -h/2), # 3 -> D
(0., b, h/2), # 4 -> A'
(c, b, h/2), # 5 -> B'
(0., b, -h/2), # 6 -> C'
(c, b, -h/2)]) # 7 -> D'
# Define faces by sequence of points
faces = np.array([(0,1,5,4), (1,2,6,5), (2,3,7,6), (3,0,4,7)])
and then it would continue with the discretization of the faces and returning a list with all the elements of the unstructured mesh, where each element has a reference to its nodes (both in terms of ids and coordinates).
I have seen that there are libraries like pyvista
and gmsh
, but I got the impression that they are more oriented towards working with meshes imported from files rather than actually produce a mesh and the mesh connectivity information from some coordinates like I want to do.
pyvista
can also be used to generate meshes using Polydata()
:
Dataset consisting of surface geometry (e.g. vertices, lines, and polygons).
Can be initialized in several ways:
- Create an empty mesh
- Initialize from a vtk.vtkPolyData
- Using vertices
- Using vertices and faces
- From a file
There are also some helper functions for simple geometric objects, e.g. Box
(it uses quadrilateral elements by default):
import pyvista
mesh = pyvista.Box((0, c, 0, b, -h/2, h/2), level=10, quads=True)
print(mesh)
#PolyData (0x197125e5f40)
# N Cells: 726
# N Points: 728
# X Bounds: 0.000e+00, 1.000e+03
# Y Bounds: 0.000e+00, 9.000e+03
# Z Bounds: -5.000e+01, 5.000e+01
# N Arrays: 0
for i in range(mesh.number_of_cells):
print(mesh.cell_points(i))
#[[ 0. 0. -50. ]
# [ 0. 0. -40.90909195]
# [ 0. 818.18182373 -40.90909195]
# [ 0. 818.18182373 -50. ]]
# ...
You can cast PolyData
to UnstructuredGrid
using cast_to_unstructured_grid
.
For more information see the Data Model section of the user guide.