0% found this document useful (0 votes)
101 views12 pages

Matlab Code - 2D Structured and Unstructred Mesh

The document provides a Matlab script for generating a simple 2D structured and unstructured mesh. The script defines functions for reading mesh data, refining the mesh, plotting the mesh, and testing mesh validity. It then demonstrates generating an initial quadrilateral mesh, repeatedly refining it, and converting it to a triangular mesh.

Uploaded by

Abhiyan Paudel
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
101 views12 pages

Matlab Code - 2D Structured and Unstructred Mesh

The document provides a Matlab script for generating a simple 2D structured and unstructured mesh. The script defines functions for reading mesh data, refining the mesh, plotting the mesh, and testing mesh validity. It then demonstrates generating an initial quadrilateral mesh, repeatedly refining it, and converting it to a triangular mesh.

Uploaded by

Abhiyan Paudel
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 12

See

discussions, stats, and author profiles for this publication at: https://www.researchgate.net/publication/278786548

Matlab Script for Generating a simple 2D


structured and unstructured mesh
Research June 2015
DOI: 10.13140/RG.2.1.2092.5603

CITATIONS

READS

88

1 author:
Mayur Pal
Maersk Oil
68 PUBLICATIONS 251 CITATIONS
SEE PROFILE

Some of the authors of this publication are also working on these related projects:

Finite Element Based Matlab Solver for Poission's Equation View project
GIAN - Course on Integrated Subsurface flow and solute transport in porous medium - Opportunities
and Challenges View project

All content following this page was uploaded by Mayur Pal on 21 June 2015.
The user has requested enhancement of the downloaded file.

Matlab Code Creating a 2-D Simple Mesh Structured and Unstructured

Matlab Code Starts Here: For usage Copy and Paste


function [nodes,xnod,ynod,bnod] = main(nrefine)

% function [nodes,xnod,ynod,nele,tri] = main(nrefine)


% Input Argument: nrefine ===> No of speficied mesh refinements
% Output Arguments
% nodes : Mesh Connectivity
% xnod : coloumn vector containing X - coordinates of the mesh
% ynod : coloumn vector containing Y - coordinates of the mesh
% nele : total no of mesh elements in case of quad mesh
% tri
: total no of mesh elements in case of triangular mesh
% Function Created by M.Pal 12th March 07
% Copyright M.Pal @ Meshzen
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Creating Input Data file:
%
%
20____21_____22______23______24
% !
!
!
!
!
% !
!
!
!
!
%15!______!16____!17_____!18_____!19
% !
!
!
!
%11!______!12
13!_______!14
% !
!
!
!
% !6_____!_7____8______9!_______!10
% !
!
!
!
!
% !
!
!
!
!
% !______!______!_______!_______!
% 1
2
3
4
5
% To draw a mesh on above domain 4 input file have to be created
% xnod.dat ; ynod.dat; nodes.dat; bnod.dat
% xnod contains nodal coordinates in x direction for the above domain
% ynod contains nodal coordinates in y direction for the above domain
% nodes contains nodal connectivity of the elements
% bnod contain values 0 and 1, 0 is the node is inside the domain and 1
% if the node is on the bounday of the domain.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
close all;
clc;
nrefine = 4;
disp('Generating Mesh')
[nodes,xnod,ynod,bnod,nele,nno] = readquad;

%initial quadrilateral mesh

for i=1:nrefine
%refine mesh
[nodes,bnod,xnod,ynod] = refine(nodes,bnod,xnod,ynod);
end
nele = size(nodes,1);nno = length(xnod);
figure;
plotmesh(xnod,ynod,nodes)

title(['Quad mesh containing ',num2str(nele), ' mesh elements']);


tri = triangulate(xnod,ynod,nodes);
%triangulate
figure;
plotmesh(xnod,ynod,tri);
title(['Triangular mesh containing ',num2str(length(tri)), ' mesh
elements']);
figure;
[tri1,xnod,ynod] = triangulate_delaunay(xnod,ynod,nodes,bnod);
plotmesh(xnod,ynod,tri1);
title(['Triangular mesh using delaunay containing
',num2str(length(tri1)), ' mesh elements']);
clear;
disp('exit')
function [t] = eliminate_tri(cg,xnod,ynod,bnod,boundary_nodes,tri);
% function [t] = eliminate_tri(cg,xnod,ynod,bnod,boundary_nodes);
% Output Argument: ==> t
: Triangular Elementds to be eliminated as
%
they lie outside the domain.
%
% Input Arguments:
% nodes : Mesh Connectivity.
% xnod : coloumn vector containing X - coordinates of the mesh.
% ynod : coloumn vector containing Y - coordinates of the mesh.
% boundary_nodes: coloumn vector containing boundary nodes numbering.
% cg
: vector containing the x and y coordinates of cg of triangles.
% Function Created by M.Pal 12th March 07
% Copyright M.Pal @ Meshzen
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This function has to be improved for every domain.
t = [find(((cg(:,1) > 0.25)&(cg(:,1) < 0.75))&((cg(:,2) > 0.25)&(cg(:,2)
< 0.75)))]; % finds the index of the triangle to be eliminated
function nodesn = meshtest(nodes,xnod,ynod)
%
% nodesn = meshtest(nodes,xnod,ynod)
%
% applies different test in order to ensure that the quadrilateral mesh
% given by the data is admissible. Note: nodesn differs from nodes only if
% some elements are not numbered counterclockwise. In nodesn, all
% quadrilaterals are numbered counterclockwise.
%
%
if ~all(nodes(:,1)-nodes(:,2))
error('Degenerated quadrilaterals
end
if ~all(nodes(:,1)-nodes(:,3))
error('Degenerated quadrilaterals
end
if ~all(nodes(:,1)-nodes(:,4))
error('Degenerated quadrilaterals
end
if ~all(nodes(:,2)-nodes(:,3))
error('Degenerated quadrulaterals
end
if ~all(nodes(:,2)-nodes(:,4))

...')
...')
...')
...')

error('Degenerated quadrilaterals ...')


end
if ~all(nodes(:,3)-nodes(:,4))
error('Degenerated quadrilaterals ...')
end
nele = size(nodes,1);
for i = 1:nele
ind = nodes(i,[1,2,3]);
j = nodes(i,4);
b = [xnod(ind)';ynod(ind)';ones(1,3)];
if all(b\[xnod(j);ynod(j);1] > -1e-5) % This is a safety value!!
error('Nonconvex quadrilateral ...')
end
ind = nodes(i,[1,2,4]);
j = nodes(i,3);
b = [xnod(ind)';ynod(ind)';ones(1,3)];
if all(b\[xnod(j);ynod(j);1] > -1e-5)
error('Nonconvex quadrilateral ...')
end
ind = nodes(i,[1,3,4]);
j = nodes(i,2);
b = [xnod(ind)';ynod(ind)';ones(1,3)];
if all(b\[xnod(j);ynod(j);1] > -1e-5)
error('Nonconvex quadrilateral ...')
end
ind = nodes(i,[2,3,4]);
j = nodes(i,1);
b = [xnod(ind)';ynod(ind)';ones(1,3)];
if all(b\[xnod(j);ynod(j);1] > -1e-5)
error('Nonconvex quadrilateral ...')
end
end
for i = 1:nele
i1 = nodes(i,1);
i2 = nodes(i,2);
i3 = nodes(i,3);
i4 = nodes(i,4);
b = [xnod(i1)-xnod(i3),xnod(i2)-xnod(i4); ...
ynod(i1)-ynod(i3),ynod(i2)-ynod(i4)];
if rcond(b) > 1e-14
% This is a safety factor!!
x = b\[xnod(i4)-xnod(i3);ynod(i4)-ynod(i3)];
if all(x >= 0) & all(x <= 1)
error('Severely nonconvex quadrilateral ...')
end
end
i1 = nodes(i,2);
i2 = nodes(i,3);
i3 = nodes(i,4);
i4 = nodes(i,1);
b = [xnod(i1)-xnod(i3),xnod(i2)-xnod(i4); ...
ynod(i1)-ynod(i3),ynod(i2)-ynod(i4)];
if rcond(b) > 1e-14
% This is a safety factor!!
x = b\[xnod(i4)-xnod(i3);ynod(i4)-ynod(i3)];
if all(x >= 0) & all(x <= 1)
error('Severely nonconvex quadrilateral ...')
end
end
end

for i = 1:nele
ind = nodes(i,[1,2,3]);
if det([xnod(ind)';ynod(ind)';ones(1,3)]) < 0
warning('Introducing positive orientation ....')
nodes(i,:) = nodes(i,[1,3,2,4]);
end
end
% Testing of planarity. The above tests are assumed to be successful!
nno = max(max(nodes));
M = 10*nele+1;
htable = zeros(M,1);
nodesn = [nodes,nodes(:,1)];
for k = 1:nele
for i = 1:4
key = nodesn(k,i)+(nno-1)*nodesn(k,i+1);
pos = key - M*floor(key/M)+1;
while 1
switch htable(pos)
case 0
htable(pos) = key;
break
case key
error('Double edge ...')
otherwise
pos = pos+1;
if pos > M
pos = 1;
end
end
end
end
end
nodesn = nodes;
function plotmesh(xnod,ynod,nodes,fkt)
%
% plotmesh(xnod,ynod,nodes,fkt)
%
%
plotmesh plots an unstrucured grid in 2D
%
%
nn = nodes(:); % nodes in a long list
xx = xnod(nn); yy = ynod(nn); %coordinates corresponding to nodes
zz = fkt(nn);
xplot = reshape(xx,size(nodes));
yplot = reshape(yy,size(nodes));
zplot = reshape(zz,size(nodes));
clf;
axis equal;
%
fill(xplot',yplot','w');
fill3(xplot',yplot',zplot',zplot')
function plotmesh(xnod,ynod,nodes)
%
% plotmesh(xnod,ynod,nodes)
%
%
plotmesh plots an unstrucured grid in 2D
%

%
nn = nodes(:); % nodes in a long list
xx = xnod(nn); yy = ynod(nn); %coordinates corresponding to nodes
xplot = reshape(xx,size(nodes));
yplot = reshape(yy,size(nodes));
%
zplot = 0.001*sin(2*pi*xplot).*cos(2*pi*yplot);
clf;
axis equal;
fill(xplot',yplot','w');
%
fill3(xplot',yplot',zplot',zplot')
function [nodes,xnod,ynod,bnod,nele,nnot] = readq(ext)
% function [nodes,xnod,ynod,bnod,nele,nnot] = readq(ext)
% Input Argument: nrefine ===> Read the quadrilateral mesh from the files
'xcoor', 'ycoor', 'bnode',
% 'nodes'. The file 'nodes' contains the nodes rowwise, i.e. first the
four
% nodes of the first element, then the four nodes of the second element
% and so on. The argument ext contains the file extension if present.
% If ext='foo', the files to be read are 'xcoor.foo' and so on.
%
%
%
%
%
%
%

Output Arguments
nodes : Mesh Connectivity
xnod : coloumn vector containing X - coordinates of the mesh
ynod : coloumn vector containing Y - coordinates of the mesh
bnod : Boundary node
nele : total no of mesh elements in case of quad mesh
nnot : total no of nodes

% Function Created by M.Pal 12th March 07


% Copyright M.Pal @ Meshzen
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ex = '';
if nargin > 0
ex = ['.',ext];
end
xnod = dlmread(['xcoor',ex]);
ynod = dlmread(['ycoor',ex]);
bnod = dlmread(['bnode',ex]);
nno = length(xnod);
if length(ynod) ~= nno | length(bnod) ~= nno
error('Global coordinates errorneous ...')
end
if ~all(bnod == 0 | bnod == 1)
error('Wrong boundary indicator ...')
end
nodes = dlmread(['nodes',ex]);
nele = floor(length(nodes(:))/4);
if nele*4 ~= length(nodes(:))
error('Wrong number of numbers in nodes ...')
end
nodes = reshape(nodes,[4,nele])';
nodes = meshtest(nodes,xnod,ynod);
% Compute the correct number of nodes
tv = zeros(size(xnod));
for i = 1:4
tv(nodes(:,i)) = 1;

end
nnot = sum(tv);
% Eliminate unused nodes
if nnot ~= nno
iv = find(tv);
xnod = xnod(iv);
ynod = ynod(iv);
bnod = bnod(iv);
p = zeros(1,nno);
p(iv) = 1:nnot;
nodes = p(nodes);
end
function [nodesn,bnodn,xnodn,ynodn] = refine(nodes,bnode,xnod,ynod)
%
% [nodesn,bnodn,xnodn,ynodn] = refine(nodes,bnod,xnod,ynod)
%
% refines a quadrilateral mesh once.
%
nele = size(nodes,1);
nno = length(xnod);
nbn = sum(bnode);
nnon = nno+3*nele+nbn/2;
nelen = 4*nele;
nodesn = zeros(nelen,4);
bnodn = zeros(nnon,1);
xnodn = zeros(nnon,1);
ynodn = zeros(nnon,1);
bnodn(1:nno) = bnode;
xnodn(1:nno) = xnod;
ynodn(1:nno) = ynod;
sum_1 = ones(1,4)/4.;
check = sparse(1,1,0,nno,nno,10*nno);
idxn = 1;
nno = nno+1;
for iel = 1:nele
%

new nodes
iv = nodes(iel,:);
xnodn(nno) = sum_1*xnod(iv);
ynodn(nno) = sum_1*ynod(iv);
nodmid = nno;
nno = nno+1;
if check(iv(1),iv(2)) == 0
xnodn(nno) = (xnod(iv(1))+xnod(iv(2)))/2.;
ynodn(nno) = (ynod(iv(1))+ynod(iv(2)))/2.;
check(iv(1),iv(2)) = nno; check(iv(2),iv(1)) = nno;
if bnodn(iv(1)) == 1 & bnodn(iv(2)) == 1
bnodn(nno) = 1;
end
nno = nno+1;
end
if check(iv(3),iv(2)) == 0
xnodn(nno) = (xnod(iv(3))+xnod(iv(2)))/2.;
ynodn(nno) = (ynod(iv(3))+ynod(iv(2)))/2.;
check(iv(3),iv(2)) = nno; check(iv(2),iv(3)) = nno;

if bnodn(iv(3)) == 1 & bnodn(iv(2)) == 1


bnodn(nno) = 1;
end
nno = nno+1;
end
if check(iv(3),iv(4)) == 0
xnodn(nno) = (xnod(iv(3))+xnod(iv(4)))/2.;
ynodn(nno) = (ynod(iv(3))+ynod(iv(4)))/2.;
check(iv(3),iv(4)) = nno; check(iv(4),iv(3)) = nno;
if bnodn(iv(3)) == 1 & bnodn(iv(4)) == 1
bnodn(nno) = 1;
end
nno = nno+1;
end
if check(iv(1),iv(4)) == 0
xnodn(nno) = (xnod(iv(1))+xnod(iv(4)))/2.;
ynodn(nno) = (ynod(iv(1))+ynod(iv(4)))/2.;
check(iv(1),iv(4)) = nno; check(iv(4),iv(1)) = nno;
if bnodn(iv(1)) == 1 & bnodn(iv(4)) == 1
bnodn(nno) = 1;
end
nno = nno+1;
end
ivn = [iv(1) check(iv(1),iv(2)) nodmid check(iv(1),iv(4))];
nodesn(idxn,:) = ivn;
ivn = [check(iv(1),iv(2)) iv(2) check(iv(2),iv(3)) nodmid];
nodesn(idxn+1,:) = ivn;
ivn = [nodmid check(iv(3),iv(2)) iv(3) check(iv(3),iv(4))];
nodesn(idxn+2,:) = ivn;
ivn = [check(iv(1),iv(4)) nodmid check(iv(3),iv(4)) iv(4)];
nodesn(idxn+3,:) = ivn;
idxn = idxn+4;
end
%

meshtest(nodesn,xnodn,ynodn);

function tri = triangulate(xnod,ynod,nodes)


%
% tri = triangulate(xnod,ynod,nodes)
%
%
triangulate the quadrilateral mesh
%
nele = size(nodes,1);
tri = zeros(3,2*nele)';
iv = [];
ii1 = [2 3 1];
jj1 = [4 1 3];
ii2 = [1 2 4];
jj2 = [2 3 4];
nrtri = 0;
for iel = 1:nele
iv = nodes(iel,:);
d1 = norm([xnod(iv(1))-xnod(iv(3));ynod(iv(1))-ynod(iv(3))]);
d2 = norm([xnod(iv(2))-xnod(iv(4));ynod(iv(2))-ynod(iv(4))]);
if d1 < d2

nrtri = nrtri+1;
tri(nrtri,:) = iv(ii1);
nrtri = nrtri+1;
tri(nrtri,:) = iv(jj1);
else
nrtri = nrtri+1;
tri(nrtri,:) = iv(ii2);
nrtri = nrtri+1;
tri(nrtri,:) = iv(jj2);
end
end
function [tri,xnod,ynod] = triangulate_delaunay(xnod,ynod,nodes,bnod);

% function [tri] = triangulate_delaunay(xnod,ynod,nodes);


% Output Argument: ==> tri
: Total no
triangular mesh
%
xnod : modified
%
ynod : modified
% Input Arguments
% nodes : Mesh Connectivity
% xnod : coloumn vector containing X % ynod : coloumn vector containing Y -

of mesh elements in case of


nodal values in x
nodal values in y
coordinates of the mesh
coordinates of the mesh

% Function Created by M.Pal 12th March 07


% Copyright M.Pal @ Meshzen
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

tri = delaunay(xnod,ynod);
% calling matlab delaunay function
v1=tri(:,1);
v2=tri(:,2);
v3=tri(:,3);
d = (xnod(v2)-xnod(v1)).*(ynod(v3)-ynod(v1)) - (xnod(v3)ynod(v1)).*(ynod(v2)-ynod(v1));
% rearranging delaunay tessellations
rvrs = d>0;
tri(rvrs,:)=[tri(rvrs,1) tri(rvrs,3) tri(rvrs,2)];
% Testting critera to eleminate triangles generated on empty region by
% delaunay

% calculate centroid of the triangles


Cg =
[(xnod(tri(:,1))+xnod(tri(:,2))+xnod(tri(:,3)))/3,(ynod(tri(:,1))+ynod(tri(
:,2))+ynod(tri(:,3)))/3];
boundary_nodes = [find(bnod==1)];
% finding boundary nodes
[t] = eliminate_tri(Cg,xnod,ynod,bnod,boundary_nodes,tri); % function
returns the triangles to be eliminated.
tri(t,:)=[];
% finds the index of the triangle to be
eliminated
numx = length(xnod);
numy = length(ynod);
X_rand = (rand(length(xnod)))/((numx)); % Generate random Perturbation
in x

Y_rand = (rand(length(ynod)))/((numx)); % Generate random Perturbation


in y
X_rand = X_rand(:,1);
values
Y_rand = Y_rand(:,1);
x_boundary = xnod(boundary_nodes);
y_boundary = ynod(boundary_nodes);
xnod = xnod+X_rand;
ynod = ynod+Y_rand;
xnod(boundary_nodes)=x_boundary;
intact
ynod(boundary_nodes)=y_boundary;

% Removing unnecessary
% storing boundary nodes
% adding perturbation
% keeping boundary nodes

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% INPUT FILES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%bnode%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% copy lines below and save in bnode.txt
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
%nodes%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% save as nodes.txt lines below
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1
2
7
6
2
3
8
7
3
4

9
8
4
5
10
9
6
7
12
11
9
10
14
13
11
12
16
15
13
14
19
18
15
16
21
20
16
17
22
21
17
18
23
22
18
19
24
23
%xcoor%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% save as xcoor.txt lines below
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0.0
0.25
0.5
0.75
1.0
0.0
0.25
0.5
0.75
1.0
0.0
0.25
0.75
1.0
0.0
0.25
0.5
0.75
1.0
0.0

0.25
0.5
0.75
1.0
%ycoor%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% save as ycoor.txt lines below
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0.0
0.0
0.0
0.0
0.0
0.25
0.25
0.25
0.25
0.25
0.5
0.5
0.5
0.5
0.75
0.75
0.75
0.75
0.75
1.0
1.0
1.0
1.0
1.0

View publication stats

You might also like