demo12_gmsh of Im2mesh package
Use polyshape to define geometry and generate mesh via Gmsh
Note
If you plan to generate quadrilateral mesh, please download gmsh-4.13 or gmsh-4.14. I encountered a bug when using gmsh-4.15 to generate quadrilateral mesh.
Initialize
Before starting, we need to download Gmsh and un-zip.
Please set folder "Im2mesh_Matlab" as your current folder of MATLAB.
Set default image size.
x = 250; y = 250; width = 300; height = 300;
set(groot, 'DefaultFigurePosition', [x,y,width,height])
% set(groot, 'DefaultFigurePosition', 'factory')
We add the folder 'mesh2d-master' to the path of MATLAB.
addpath(genpath('mesh2d-master'))
Single-part geometry
A polyshape
Let's create a polyshape (for a single-part geometry).
Suppose we want a square with a hole.
vertex = 10*[ 0 0; 1 0; 1 1; 0 1 ];
psSq = polyshape(vertex);
Create a circle.
psCircle = polyshape(x1,y1);
Plot them together.
plot( [psSq; psCircle] );
Perform boolean operation to create a square with a hole.
psSqHole = subtract(psSq, psCircle);
Polygonal boundary
We use function polyshape2bound to convert a cell array of polyshape to a cell array of polygonal boundary.
psCell = {psSqHole}; % psCell is a cell array of polyshape
bounds = polyshape2bound(psCell);
% plot boundaries and show all vertices
plotBounds(bounds,false,'ko-')
Simplify boundaries
We want to reduce the number of vertices on the circle.
boundsCtrlP = getCtrlPnts( bounds );
% simplify polyline using Douglas-Peucker algorithm
boundsReduced = simplifyBounds( boundsCtrlP, tolerance );
plotBounds( boundsReduced, false, 'ko-' );
Generate mesh via Gmsh
We need to know the location of gmesh.exe
path_to_gmsh = 'C:\Users\Jason\Downloads\gmsh-4.13.1-Windows64\gmsh.exe';
We can use Gmsh to generate triangular or quadrilateral mesh. Please refer to demo11 to learn about the meaning of the following functions.
Let's generate quasi-structured quadrilateral mesh.
path_to_geo = 'gmshTemp.geo';
bounds2geo( boundsReduced, path_to_geo, opt );
bounds2geo Done! Check the geo file!
Send geo file to Gmsh.
path_to_m = 'gmshTemp.m';
str=sprintf('"%s" "%s" -o "%s" -v %i -save', ...
path_to_gmsh, path_to_geo, path_to_m, verbosity );
system(str);
Warning : SurfaceProjector initialize: failed to build STL triangulation
Warning : SurfaceProjector initialize: failed to build STL triangulation
Warning : SurfaceProjector initialize: failed to build STL triangulation
Warning : SurfaceProjector initialize: failed to build STL triangulation
Warning : ------------------------------
Warning : Mesh generation error summary
Warning : 4 warnings
Warning : 0 errors
Warning : Check the full log for details
Warning : ------------------------------
% struct variable 'msh' in the workspace of MATLAB
msh
msh =
nbNod: 410
POS: [410×3 double]
MAX: [10 10 0]
MIN: [0 0 0]
QUADS: [358×5 double]
Before ploting the mesh, we need to do some processing to the mesh data.
[vert,ele] = extractMsh( msh );
Plot mesh.
Awesome! Please refer to demo11 for how to evaluate mesh quality.
Multi-part geometry
Multiple polyshapes
Let's create multiple polyshapes for multi-part geometry.
Start with a square.
vertex = 10*[ 0 0; 1 0; 1 1; 0 1 ];
psSq = polyshape(vertex);
Create three rods - A B C, and combine them using function union.
psRodBase = scale( psSq, [1, 0.05]);
psRodA = rotate( psRodBase, 155 );
psRodA = translate( psRodA, [6 8] );
psRodB = translate( psRodBase, [1 9] );
psRodC = translate( psRodBase, [-1 5] );
psRodABC = union([ psRodA; psRodB; psRodC ]);
Create a circle.
psCircle = polyshape(x1,y1);
Plot them together.
plot( [psRodABC; psSq; psCircle] );
We saw that they are overlapped.
Boolean operations
We use boolean operations to remove overlapped regions.
psBlock = subtract( psSq, psRodABC );
psBlock = subtract( psBlock, psCircle );
psRodABC = subtract( psRodABC, psCircle );
plot( [psRodABC; psBlock; psCircle] );
Cell array of polyshape
We put them into a cell array - psCell. Each element in psCell represent different parts. It's like labelling.
psCell = { psRodABC; psBlock; psCircle };
for i = 1: length(psCell)
Add intersect points
Polyshape objects are not able to find intersect points automatically. Therefore, we convert the cell array of polyshape 'psCell' to a cell array of polygonal boundaries 'bounds', and use function addIntersectPnts to add intersect points to 'bounds'.
Note that if we don't add intersect points, mesh generation may fail.
bounds = polyshape2bound(psCell);
tol_intersect = 1e-6; % distance tolerance for intersect
bounds = addIntersectPnts( bounds, tol_intersect );
% plot boundaries and show all vertices
plotBounds(bounds,false,'ko-')
We saw that there are a lot of vertices on the circle.
Simplify boundaries
We want to reduce the number of vertices on the circle.
boundsCtrlP = getCtrlPnts( bounds );
% simplify polyline using Douglas-Peucker algorithm
boundsReduced = simplifyBounds( boundsCtrlP, tolerance );
plotBounds(boundsReduced,false,'ko-')
Awesome! We saw that the number of vertices on the circle reduced a lot.
Note that you need to adjust the value of tolerance to achieve your desired reduction.
Generate mesh via Gmsh
We need to know the location of gmesh.exe
path_to_gmsh = 'C:\Users\Jason\Downloads\gmsh-4.13.1-Windows64\gmsh.exe';
We can use Gmsh to generate triangular or quadrilateral mesh. Please refer to demo11 to learn about the meaning of the following functions.
Let's generate unstructured quadrilateral mesh.
path_to_geo = 'gmshTemp.geo';
bounds2geo( boundsReduced, path_to_geo, opt );
bounds2geo Done! Check the geo file!
Send geo file to Gmsh.
path_to_m = 'gmshTemp.m';
str=sprintf('"%s" "%s" -o "%s" -v %i -save', ...
path_to_gmsh, path_to_geo, path_to_m, verbosity );
system(str);
Warning : Cannot apply Blossom: odd number of triangles (7) in surface 4
Warning : Cannot apply Blossom: odd number of triangles (161) in surface 5
Warning : ------------------------------
Warning : Mesh generation error summary
Warning : 2 warnings
Warning : 0 errors
Warning : Check the full log for details
Warning : ------------------------------
% struct variable 'msh' in the workspace of MATLAB
msh
msh =
nbNod: 643
POS: [643×3 double]
MAX: [11 12.2262 0]
MIN: [-3.2744 0 0]
QUADS: [590×5 double]
Before ploting the mesh, we need to do some processing to the mesh data.
[vert,ele,tnum] = extractMsh( msh );
180 negative area elements are fixed.
Plot mesh.
plotMeshes( vert, ele, tnum )
Awesome! Please refer to demo11 for how to evaluate mesh quality.
set(groot, 'DefaultFigurePosition', 'factory')