I would like to analyze the process of deformation of an object of elastic material when it is subjected to a squeezing force using a tetrahedral mesh that I have defined. I would like to know why the code I wrote didn’t work. I hope someone can solve my problem. Using dolfinx version 0.8.0 libraries
import numpy as np
import dolfinx
import ufl
from mpi4py import MPI
from scipy.spatial import Delaunay, ConvexHull
import dolfinx.mesh
import dolfinx.io
import basix
import open3d as o3d
import dolfinx.fem.petsc
def read_point_cloud(filename):
points = np.loadtxt(filename, delimiter=" ")
points = points[:, 0:3]
return points
def create_tetrahedral_mesh(points, simplices):
tetrahedra = simplices
element = basix.ufl.element("CG", 'tetrahedron', 1, shape=(3,))
mesh_tetrahedral = dolfinx.mesh.create_mesh(MPI.COMM_WORLD, tetrahedra,points, element)
return mesh_tetrahedral
def tetrahedron_edge_lengths(vertices):
edges = [
np.linalg.norm(vertices[i] - vertices[j])
for i in range(4) for j in range(i + 1, 4)
]
return edges
def dense_point(points):
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(points)
sparse_pcd = pcd
points = np.asarray(sparse_pcd.points)
hull = ConvexHull(points)
mesh = o3d.geometry.TriangleMesh.create_from_point_cloud_alpha_shape(sparse_pcd, 0.03)
mesh.compute_vertex_normals()
voxel_size = 0.006
voxel_grid = o3d.geometry.VoxelGrid.create_from_triangle_mesh_within_bounds(
mesh, voxel_size, mesh.get_min_bound(), mesh.get_max_bound())
def is_point_in_hull(point, hull):
return np.all(np.dot(hull.equations[:, :-1], point) + hull.equations[:, -1] <= 1e-12)
dense_points = []
for voxel in voxel_grid.get_voxels():
voxel_center = voxel.grid_index * voxel_grid.voxel_size + voxel_grid.origin
if is_point_in_hull(voxel_center, hull):
dense_points.append(voxel_center)
dense_pcd = o3d.geometry.PointCloud()
dense_pcd.points = o3d.utility.Vector3dVector(np.array(dense_points))
merged_pcd = sparse_pcd + dense_pcd
points = np.asarray(merged_pcd.points)
return points
def exclud_tetrahedron(points, length_threshold):
tri = Delaunay(points)
used_points_indices = set()
filtered_simplices = []
for simplex in tri.simplices:
edge_lengths = tetrahedron_edge_lengths(points[simplex])
if all(length < length_threshold for length in edge_lengths):
filtered_simplices.append(simplex)
used_points_indices.update(simplex)
return filtered_simplices, used_points_indices
def epsilon(u):
return ufl.sym(ufl.grad(u))
def sigma(u):
return lmbda * ufl.tr(epsilon(u)) * ufl.Identity(3) + 2 * mu * epsilon(u)
def boundary(x):
return np.isclose(x[2], 0)
# return np.full(x.shape[0], np.isclose(x[:, 2], 0))
def normalize_point_cloud(points):
centroid = np.mean(points, axis=0)
normalized_points = points - centroid
return normalized_points
#################################
if __name__ == "__main__":
points = read_point_cloud("/home/jiao/chen_test/code/2f347d95d4a2dae3e762cf5917cef4ef.txt")
points = dense_point(points)
one = Delaunay(points).simplices
# print(type(one))
simplices, used_points_indices = exclud_tetrahedron(points, 0.05)
filtered_dense_points_all = points[list(used_points_indices)]
simplices_dense, used_points_indices_dense = exclud_tetrahedron(filtered_dense_points_all, 0.05)
finally_simplices = np.array(simplices_dense)
tetrahedral_mesh = create_tetrahedral_mesh(filtered_dense_points_all, finally_simplices)
tetrahedral_mesh_deformed = create_tetrahedral_mesh(filtered_dense_points_all, finally_simplices)
#################################
E = 1000
nu = 0.3
mu = E / (2 * (1 + nu))
lmbda = E * nu / ((1 + nu) * (1 - 2 * nu))
#################################
V = dolfinx.fem.functionspace(tetrahedral_mesh, ("CG", 1 ,(tetrahedral_mesh.geometry.dim,)))
#################################
u_bc = dolfinx.fem.Function(V)
u_bc.interpolate(lambda x: np.zeros((3, x.shape[1])))
bc = dolfinx.fem.dirichletbc(u_bc, dolfinx.fem.locate_dofs_geometrical(V, boundary))
#################################
u = ufl.TrialFunction(V)
v = ufl.TestFunction(V)
a = ufl.inner(sigma(u), epsilon(v)) * ufl.dx
L = ufl.inner(dolfinx.fem.Constant(tetrahedral_mesh, np.array([0.0, 0.0, -10000.0], dtype=np.float64)), v) * ufl.dx
problem = dolfinx.fem.petsc.LinearProblem(a, L, bcs=[bc])
u = problem.solve()
u_values = u.x.array
######################################
with dolfinx.io.VTKFile(MPI.COMM_WORLD, "original_mesh1.vtk", "w") as vtkfile:
vtkfile.write_mesh(tetrahedral_mesh)
original_coords = tetrahedral_mesh.geometry.x.copy()
deformed_coords = original_coords + u.vector.array.reshape(-1, 3)
tetrahedral_mesh_deformed.geometry.x[:] = deformed_coords
with dolfinx.io.VTKFile(MPI.COMM_WORLD, "deformed_mesh1.vtk", "w") as vtkfile:
vtkfile.write_mesh(tetrahedral_mesh_deformed)
######################################