Problem generating mesh with multiple subtracted volumes (Tetgen)

74
views
0
8 weeks ago by
Problem: Tetgen fails to generate a mesh if there is more than one isolated volume subtracted from the domain.
Result: The resulting mesh is missing components. Rerunning generate_mesh() may change which components are displayed.

Notes: CGal works for multiple subtractions, why not use it?
- Cgal (Left Image) is creating holes in very thin parts of the mesh. It does not preserve surfaces.
- Tetgen (Right Image) works much faster(factors of 10) and requires less cells. It does a great job with varying mesh density around smaller areas.

• I have attached an image of the real problem at the bottom. It is the interior view of a fluid filled cavity. I am trying to subtract the two cantilever blocks from the domain and generate the mesh using tetgen.
A Simplified Example: Channel containing two spheres
from mshr import *
from dolfin import *

h = 0.25 ; r = 0.3*h
box = Box(Point(0, 0, 0), Point(1, h, h))
s1 = Sphere(Point(0.2, 0.65*h, 0.65*h), r)
s2 = Sphere(Point(0.8, 0.35*h, 0.35*h), r)

domain = box-s1-s2
def Tet(): return generate_mesh(domain, 200, 'tetgen')
def CGal(): return generate_mesh(domain, 20)

print(CGal()) #Mesh Info
CGal() #This Works​

print(Tet()) #Mesh Info
Tet()#Fails. more than 1 isolated domain being subtracted. (usually only 1 sphere or box containing 1 sphere is generated)​

Attempt at a Solution:
Tetgen Works fine when there is only a single volume being subtracted. We can try partitioning the mesh so that there is at most one volume being subtracted from each component. Use Tetgen to generate a mesh for each seperate component, then merge meshes using DolfinMeshUtils.merge_meshes().
mid= abs((0.8-r)-(0.2+r))/2 # Cut between the two spheres
s1_box=Box(Point(0, 0, 0), Point(0.2+r+mid, h, h))
s2_box=Box(Point(0.8-r-mid, 0, 0), Point(1, h, h))

#Generate each mesh. Low Resolution to limit the number of vertices on interface
s1_cut_mesh= generate_mesh(s1_box-s1, 1, 'tetgen')#box1 with sphere1 removed
s2_cut_mesh= generate_mesh(s2_box-s2, 1, 'tetgen')​

#Merge Meshes
mesh=DolfinMeshUtils.merge_meshes(s1_cut_mesh,s2_cut_mesh)
mesh
Result: All components are present and the isolated volumes were subtracted from the domain(tested), however there is an interior obstruction at the interface of the two boxes. (See image below)

Questions
:
• Merge_meshes relies on the alignment of vertices.
1. Is it possible to align the interface vertices somehow?
Ideas: Manually create an addditional 'intermediate' mesh with specified vertices and join the three of them... (LocalCoarsening, Snap_boundary, ALE.move, mesh.editor)

Fenics Version: 2017.2  (Installed via Ubuntu package)
OS: Ubuntu 16.04 LTS
Community: FEniCS Project