Generate mesh based on 2D contours

For finite element analysis

Contents

Download Im2mesh package https://www.mathworks.com/matlabcentral/fileexchange/71772

Im2mesh package require Matlab Mapping toolbox

Before we start, please set folder "Im2mesh_Matlab" as your current folder of MATLAB.

Function bounds2mesh use a mesh generator called MESH2D (developed by Darren Engwirda). We can use the following command to add the folder 'mesh2d-master' to the path of MATLAB.

addpath(genpath('mesh2d-master'))
clear all

Example 1

Define Z, interested level, and outer boundary

Z = peaks;      % Z is a 49-by-49 matrix containing the height values of
                % the surface with respect to the x-y plane.

level = 1.5;    % interested level

% outer boundary
xmin = 0;
xmax = 50;
ymin = 5;
ymax = 55;

Plot surface

surf(Z)

Plot contour

contour(Z, [level,level]);

Store vertices in countour

C = contourc(Z, [level,level]);

contourCell = {};   % a cell array for vertices in countours
k = 1;              % current column in C

while k < size(C,2)
    nv = C(2,k);           % number of vertices
    idx  = k+1 : k+nv;     % columns that hold the vertices
    xy = C(1:2,idx)';      % nv-by-2 array
    contourCell{end+1} = xy;

    k = k + nv + 1;       % jump to next header
end

Plot contourCell

figure
hold on; axis equal
for i = 1: length(contourCell)
    plot( contourCell{i}(:,1), contourCell{i}(:,2) )
end
hold off

Convert contourCell to polyshape object

x_temp = [];
y_temp = [];

for i = 1: length(contourCell)
    x_temp = [ x_temp; NaN; contourCell{i}(:,1) ];
    y_temp = [ y_temp; NaN; contourCell{i}(:,2) ];
end

psIn = polyshape( x_temp, y_temp  );

Plot polyshape object

plot(psIn);
axis equal

create polyshape for outer boundary

vertex = [xmin ymin; xmax ymin; xmax ymax; xmin ymax; xmin ymin];
psOB = polyshape(vertex);   % polyshape for outer boundary

Boolean operation

psOB = subtract(psOB, psIn);

plot

figure
hold on; axis equal
plot(psOB);
plot(psIn);
hold off

Convert to a nested cell array of polygons

psCell = {psOB; psIn};              % a cell array of polyshape
bounds = polyshape2bound(psCell);   % a nested cell array of polygons
tol_intersect = 1e-6;
bounds = addIntersectPnts( bounds, tol_intersect );

% plot polygons and show all vertices
plotBounds(bounds,false,'ko-')

Reduce the number of vertices

boundsNew = getCtrlPnts( bounds, false );

tolerance = 0.1;   % For polyline simplification
                   % This value will affect the final mesh size.
                   % Increase tolerance, the min mesh size will increase.
boundsNew = simplifyBounds( boundsNew, tolerance );

% show all vertices
plotBounds(boundsNew,false,'ko-')

Generate mesh

hmax = 500;
grad_limit = 0.25;
opt = [];
opt.disp = inf;     % silence verbosity

[vert,tria,tnum,vert2,tria2] = bounds2mesh( boundsNew, hmax, grad_limit, opt );
plotMeshes(vert,tria,tnum);

We could remove the mesh in the hole if we don't want it.

hmax = 500;
grad_limit = 0.25;
opt = [];
opt.disp = inf;     % silence verbosity

[vert,tria,tnum,vert2,tria2] = bounds2mesh( boundsNew(1), hmax, grad_limit, opt );
plotMeshes(vert,tria,tnum);

Create matlab pde model object

% linear model
model_linear = createpde();
geometryFromMesh( model_linear, vert', tria', tnum' );

% qudratic model
model_quad = createpde();
geometryFromMesh( model_quad, vert2', tria2', tnum' );

Show geometry

pdegplot(model_quad, 'EdgeLabels','on','VertexLabels','on', 'FaceLabels','on' )

Show mesh

pdemesh( model_quad )
clear all

Example 2

Define Z, interested level, and outer boundary

n = -1:0.1:1;
Z = peaks(n);   % Z is a 21-by-21 matrix containing the height values of
                % the surface with respect to the x-y plane.

level = 1.5;    % interested level

% outer boundary
xmin = 1;
xmax = 21;
ymin = 1;
ymax = 21;

Plot surface

surf(Z);
view( -45 , 64 )

Plot contour

contour(Z, [level,level]);

Store vertices in countour

% add (-inf) padding to Z
Z2 = padarray(Z,[1 1],-inf,'both');

C = contourc(Z2, [level,level]);

contourCell = {};   % a cell array for vertices in countours
k = 1;              % current column in C

while k < size(C,2)
    nv = C(2,k);           % number of vertices
    idx  = k+1 : k+nv;     % columns that hold the vertices
    xy = C(1:2,idx)';      % nv-by-2 array
    contourCell{end+1} = xy -1 ;    % -1 is used to removed padding

    k = k + nv + 1;       % jump to next header
end

Plot contourCell

figure
hold on; axis equal
for i = 1: length(contourCell)
    plot( contourCell{i}(:,1), contourCell{i}(:,2) )
end
hold off

Convert contourCell to polyshape object

x_temp = [];
y_temp = [];

for i = 1: length(contourCell)
    x_temp = [ x_temp; NaN; contourCell{i}(:,1) ];
    y_temp = [ y_temp; NaN; contourCell{i}(:,2) ];
end

psIn = polyshape( x_temp, y_temp  );
Warning: Polyshape has duplicate vertices, intersections, or other
inconsistencies that may produce inaccurate or unexpected results. Input data
has been modified to create a well-defined polyshape. 

Plot polyshape object

plot(psIn);
axis equal

Create polyshape for outer boundary

vertex = [xmin ymin; xmax ymin; xmax ymax; xmin ymax; xmin ymin];
psOB = polyshape(vertex);   % polyshape for outer boundary

Plot

figure;
tiledlayout('flow')

nexttile
plot(psOB);
axis equal
title('psOB')
xlim([xmin xmax])
ylim([ymin ymax])

nexttile
plot(psIn);
axis equal
title('psIn')
xlim([xmin xmax])
ylim([ymin ymax])

Boolean operation

psOB = subtract(psOB, psIn);

Plot

figure
hold on; axis equal
plot(psOB);
plot(psIn);
hold off

Convert to a nested cell array of polygons

psCell = {psOB; psIn};              % a cell array of polyshape
bounds = polyshape2bound(psCell);   % a nested cell array of polygons
tol_intersect = 1e-6;
bounds = addIntersectPnts( bounds, tol_intersect );

% plot polygons and show all vertices
plotBounds(bounds,false,'ko-')

Reduce the number of vertices

boundsNew = getCtrlPnts( bounds, false );

tolerance = 0.07;  % For polyline simplification
                   % This value will affect the final mesh size.
                   % Increase tolerance, the min mesh size will increase.
boundsNew = simplifyBounds( boundsNew, tolerance );

% show all vertices
plotBounds(boundsNew,false,'ko-')

Generate mesh

hmax = 500;
grad_limit = 0.25;
opt = [];
opt.disp = inf;     % silence verbosity

[vert,tria,tnum,vert2,tria2] = bounds2mesh( boundsNew, hmax, grad_limit, opt );
plotMeshes(vert,tria,tnum);

Create matlab pde model object

% linear model
model_linear = createpde();
geometryFromMesh( model_linear, vert', tria', tnum' );

% qudratic model
model_quad = createpde();
geometryFromMesh( model_quad, vert2', tria2', tnum' );

Show geometry

pdegplot(model_quad, 'EdgeLabels','on','VertexLabels','on', 'FaceLabels','on' )

Show mesh

pdemesh( model_quad )
clear all

Example 3

Define Z, interested level, and outer boundary

n = -1:0.1:1;
Z = peaks(n);   % Z is a 21-by-21 matrix containing the height values of
                % the surface with respect to the x-y plane.

level = 1.5;    % interested level

% outer boundary
xmin = 1;
ymin = 1;
xmax = 21;
ymax = 21;

% Define hole
col_min = 8;      % column index
col_max = 12;
row_min = 14;     % row index
row_max = 19;
Z( row_min:row_max , col_min:col_max ) = -inf;

Plot surface

surf(Z)
view( -45 , 64 )

Plot contour

contour(Z, [level,level]);

Store vertices in countour

% add (-inf) padding to Z
Z2 = padarray(Z,[1 1],-inf,'both');

C = contourc(Z2, [level,level]);

contourCell = {};   % a cell array for vertices in countours
k = 1;              % current column in C

while k < size(C,2)
    nv = C(2,k);           % number of vertices
    idx  = k+1 : k+nv;     % columns that hold the vertices
    xy = C(1:2,idx)';      % nv-by-2 array
    contourCell{end+1} = xy -1 ;    % -1 is used to removed padding

    k = k + nv + 1;       % jump to next header
end

Plot contourCell

figure
hold on; axis equal
for i = 1: length(contourCell)
    plot( contourCell{i}(:,1), contourCell{i}(:,2) )
end
hold off

Convert contourCell to polyshape object

x_temp = [];
y_temp = [];

for i = 1: length(contourCell)
    x_temp = [ x_temp; NaN; contourCell{i}(:,1) ];
    y_temp = [ y_temp; NaN; contourCell{i}(:,2) ];
end

psIn = polyshape( x_temp, y_temp  );
Warning: Polyshape has duplicate vertices, intersections, or other
inconsistencies that may produce inaccurate or unexpected results. Input data
has been modified to create a well-defined polyshape. 

Plot polyshape object

plot(psIn);
axis equal

Create polyshape for outer boundary and hole

vertex = [xmin ymin; xmax ymin; xmax ymax; xmin ymax; xmin ymin];
psOB = polyshape(vertex);   % polyshape for outer boundary

hxmin = col_min -1;
hxmax = col_max +1;
hymin = row_min -1;
hymax = row_max +1;
vertex2 = [hxmin hymin; hxmax hymin; hxmax hymax; hxmin hymax; hxmin hymin];
psHole = polyshape(vertex2);   % polyshape for hole

Plot

figure;
tiledlayout('flow')

nexttile
plot(psOB);
axis equal
title('psOB')
xlim([xmin xmax])
ylim([ymin ymax])

nexttile
plot(psIn);
axis equal
title('psIn')
xlim([xmin xmax])
ylim([ymin ymax])

nexttile
plot(psHole);
axis equal
title('psHole')
xlim([xmin xmax])
ylim([ymin ymax])

Boolean operation to remove overlaps

psOB = subtract(psOB, psIn);
psOB = subtract(psOB, psHole);

psIn = subtract(psIn, psHole);

Plot

figure
hold on; axis equal
plot(psOB);
plot(psIn);
hold off

Convert to a nested cell array of polygons

psCell = {psOB; psIn};              % a cell array of polyshape
bounds = polyshape2bound(psCell);   % a nested cell array of polygons
tol_intersect = 1e-6;
bounds = addIntersectPnts( bounds, tol_intersect );

% plot polygons and show all vertices
plotBounds(bounds,false,'ko-')

Reduce the number of vertices

boundsNew = getCtrlPnts( bounds, false );

tolerance = 0.07;  % For polyline simplification
                   % This value will affect the final mesh size.
                   % Increase tolerance, the min mesh size will increase.
boundsNew = simplifyBounds( boundsNew, tolerance );

% show all vertices
plotBounds(boundsNew,false,'ko-')

Generate mesh

hmax = 500;
grad_limit = 0.25;
opt = [];
opt.disp = inf;     % silence verbosity

[vert,tria,tnum,vert2,tria2] = bounds2mesh( boundsNew, hmax, grad_limit, opt );
plotMeshes(vert,tria,tnum);

Create matlab pde model object

% linear model
model_linear = createpde();
geometryFromMesh( model_linear, vert', tria', tnum' );

% qudratic model
model_quad = createpde();
geometryFromMesh( model_quad, vert2', tria2', tnum' );

Show geometry

pdegplot(model_quad, 'EdgeLabels','on','VertexLabels','on', 'FaceLabels','on' )

Show mesh

pdemesh( model_quad )

end