Вы находитесь на странице: 1из 24

AS5410 : Grid Generation : Project Report : Unstructured

Grid Generation over NACA 0012 Airfoil


December 6, 2015
Athul P G : [AE11B039]
Abstract
In this assignment we generate an unstructured grid over the NACA 0012 airfoil using an initial triangulation
creates by joining the diagonal quadrilateral elements from an elliptic grid. The flip algorithm is used to make the
initial triangulation Delaunay. The initial and final triangulations along with their grid quality index is plotted.

Contents
1 Introduction

2 Methodology

3 Data Structures and Routines for the Flip Algorithm


3.1 Step 1 : Create the Table of Edges . . . . . . . . . . . . . . . .
3.2 Step 2 : Create the Table of Triangles . . . . . . . . . . . . . .
3.3 Step 3 : Map the Edges to Their Respective Triangle Elements
3.4 Step 4 : Define Some More Required Routines . . . . . . . . . .
3.4.1 dist(x1,y1,x2,y2) . . . . . . . . . . . . . . . . . . . . . .
3.4.2 isDelaunay(edge point,left point,right point) . . . . . .
3.4.3 isBoundaryEdge(edge point) . . . . . . . . . . . . . . .
3.4.4 isExistingEdge(edge,toe) . . . . . . . . . . . . . . . . . .
3.4.5 find point(edge,triangle) . . . . . . . . . . . . . . . . . .
3.4.6 find edge index(edge,toe aux) . . . . . . . . . . . . . . .
3.5 Step 5 : Make the Triangulation Delaunay . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.

6
6
7
7
8
8
8
9
9
10
10
10

4 Results
4.1 Delauny Triangulation Plots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2 Grid Quality Plots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

13
13
15

5 Comments

17

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

List of Figures
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

Grid - Initial Triangulation . . . . . . . . . . . . . . . . . . . .


Grid - Initial Triangulation - Zoomed in near the Leading Edge
Grid - Initial Triangulation - Zoomed in near the Trailing Edge
Flip Algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . .
Flip Algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . .
Creating the Table of Edges . . . . . . . . . . . . . . . . . . . .
Creating the Table of Triangles . . . . . . . . . . . . . . . . . .
Mapping the edges to triangle elements . . . . . . . . . . . . .
dist(x1,y1,x2,y2) . . . . . . . . . . . . . . . . . . . . . . . . . .
isDelaunay(...) . . . . . . . . . . . . . . . . . . . . . . . . . . .
isBoundaryEdge(...) . . . . . . . . . . . . . . . . . . . . . . . .
isExistingEdge(...) . . . . . . . . . . . . . . . . . . . . . . . . .
find point(...) . . . . . . . . . . . . . . . . . . . . . . . . . . . .
find edge index(...) . . . . . . . . . . . . . . . . . . . . . . . . .
makeDelaunay(...) . . . . . . . . . . . . . . . . . . . . . . . . .
makeDelaunay(...) . . . . . . . . . . . . . . . . . . . . . . . . .
makeDelaunay(...) . . . . . . . . . . . . . . . . . . . . . . . . .
Final Triangulation - Delauny . . . . . . . . . . . . . . . . . . .
Final Triangulation - Delauny - Zoom 1 . . . . . . . . . . . . .
Final Triangulation - Delauny - Zoom 2 . . . . . . . . . . . . .
Final Triangulation - Delauny - Zoom 3 . . . . . . . . . . . . .
Final Triangulation - Delauny - Zoom 4 . . . . . . . . . . . . .
Grid Quality Index - Contours . . . . . . . . . . . . . . . . . .
Grid Quality Index - Contours . . . . . . . . . . . . . . . . . .
Grid Quality Index - Contours . . . . . . . . . . . . . . . . . .
Grid Quality Index - Contours . . . . . . . . . . . . . . . . . .
Grid Quality Index - Contours . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

4
4
5
5
6
6
7
8
8
9
9
9
10
10
11
12
13
14
14
14
14
15
15
16
16
16
17

Introduction

The objective of this assignment is to create an unstructured grid over the NACA 0012 airfoil. The grid is to
be composed of triangular elements which satisfy the Delaunay criterion so as to avoid skinny triangles. In this
assignment, our starting point is a set of triangles obtained by connecting the lower left and upper right points of the
grid quadrilaterals created in the earlier assignment using the elliptic grid generation method. This initial grid and a
zoomed in view near the leading edge is shown below

Figure 1: Grid - Initial Triangulation

Figure 2: Grid - Initial Triangulation - Zoomed in near the Leading Edge

Figure 3: Grid - Initial Triangulation - Zoomed in near the Trailing Edge

Methodology

In this section we explain the flip algorithm which will be used to make the initial triangulation which is not
guaranteed to be Delaunay into a triangulation which is Delaunay. According to the flip algorithm theory, if a set
of two triangles forming a non-convex quadrilateral are not Delaunay, then by flipping the diagonal edge which is
common to both the triangles as shown in the figure is guaranteed to make the two triangles Delaunay.

Figure 4: Flip Algorithm

We can use this concept to make every edge Delaunay and hence the entire triangulation Delaunay.
This is explained in detail in the next section.

Data Structures and Routines for the Flip Algorithm

Figure 5: Flip Algorithm

The essence of the flip algorithm is mentioned above and can be implemented by creating the queue which is nothing
but the Table of Non-Delaunay Edges and then carrying out the steps mentioned.

3.1

Step 1 : Create the Table of Edges

In this step we create the Table of Non-Delaunay Edges. This is a Python list(array) which holds the following information - starting and ending Point of the directed edge(from start to end) and a unique edge ID which
can be used to refer to that edge. The table of edges is a list of lists with each entry having the following list [[1 , 1 ], [2 , 2 ], EDGE ID], where subscripts 1 and 2 refer to the starting point and ending point of the edge. An example entry in the table of edges would be - [[0, 0], [1, 1]], 0], where the edge starts at the location given by [, ] = [0, 0]
and ends at [, ] = [1, 1] with a unique edge ID of 0. The table of edges is created by first adding all the diagonal
edges created by joining the lower left and the upper right points of the initial grid quadrilaterals as mentioned earlier,
then adding all the and horizontal and vertical edges assigning a unique ID such to every edge. Note that boundary
edges are not added to the Table of Edges as we are not allowed to modify them and must be kept intact. The edges
added to the table of edges are allowed to be changed and are called free edges. The routine create toe() is used to
create this table of edges. In this case there are 29800 free edges that are added to the table with edge IDs from 0 to
27999.

Figure 6: Creating the Table of Edges

3.2

Step 2 : Create the Table of Triangles

In this step, we create the Table of Triangles which will be used for flipping the edge later. This again is a Python
list which holds the following information - vertices of three edges of a triangle in an anti-clockwise manner. The table
of triangles is a list of lists with each entry having the following list - [[1 , 1 ], [2 , 2 ], [2 , 2 ] where subscripts 1,2 and
3 refer to the three points of the triangle. An example entry in the table of triangles would be - [[0, 0], [1, 0], [1, 1]]
which would indicate a triangle composed of [, ] = [0, 0], [, ] = [1, 0] and [, ] = [1, 1]. The index of each these
entries in the list(table of triangles) is used as an ID for that triangle. The table of triangles is created by adding the
left and right side triangles of each diagonal edge in the initial grid, as this encompasses all the initial triangles. For
example if [[0, 0], [1, 0], [1, 1]] is the first element in the list, then the triangle has an ID of 0. The routine create tot()
is used to create this table of triangles. In this case there are 20000 triangles that are added to the table with triangke
IDs from 0 to 19999.

Figure 7: Creating the Table of Triangles

3.3

Step 3 : Map the Edges to Their Respective Triangle Elements

In this section we create a map to relate the edges to the triangle elements to the left and right side of that edge. The
map is a python list whose entry at index i which holds the following information - [T 1 ID, T 2 ID], where T 1 ID
and T 2 ID refer to the ID of the triangle elements to the left and right of the edge with the edge index i. For
example the map entry at index 0 being [0, 1] indicates that for the edge with edge index 0, the left triangle has a
triangle ID of 0 and the right triangle has a triangle ID of 1. Due to the way in which triangle elements are numbered,
some special care needs to be taken while mapping the triangles of the horizontal and vertical edges. The routine
create toe tot ot map() is used to create this map. In this case there are 29000 entries in the map which correspond
to as many edges present.

Figure 8: Mapping the edges to triangle elements

3.4

Step 4 : Define Some More Required Routines

In this section we will define additional routines which will be used for the flip algorithm.
3.4.1

dist(x1,y1,x2,y2)

Computes the distance between (x1, y1) and (x2, y2)

Figure 9: dist(x1,y1,x2,y2)

3.4.2

isDelaunay(edge point,left point,right point)

Checks if a given edge is Delaunay or not by checking if either of the points of the two triangles forming the quad.
which are not on the common edge are inside a circle drawn with the given edge as its diameter.

Figure 10: isDelaunay(...)

3.4.3

isBoundaryEdge(edge point)

Checks if a given edge lies on the domain boundary.

Figure 11: isBoundaryEdge(...)

3.4.4

isExistingEdge(edge,toe)

Checks if a given edge already exists in the table of edges.

Figure 12: isExistingEdge(...)

3.4.5

find point(edge,triangle)

Finds the left or right point, given the edge and the left or right triangle correspondingly

Figure 13: find point(...)

3.4.6

find edge index(edge,toe aux)

Finds the edge index given an edge in the auxilliary table of edges. The auxilliary table of edges is to begin with a
copy of all the free edges, but is updated everytime a flip occurs and hence stores the current state of the grid. The
function is used to find the index of an edge in this auxilliary table.

Figure 14: find edge index(...)

3.5

Step 5 : Make the Triangulation Delaunay

This step uses functions and tables created using Steps 1-4 to make the triangulation Delaunay. The first three steps
are used to create the Table of Edges(toe), Table of Triangles(tot) and the Edges to Triangles Map(mapp). A copy of
the table of edges is stored as an Auxiliary Table of Edges(toe aux ) which is updated everytime an edge flip occurs.
The following steps are to be repeated until the toe stack is empty.
(1) Pop the first element out of the toe stack and store it in the variable edge.
(2) Pop the last entry in edge and store it in index. Now edge contains only the start and end points of the edge and
can directly be used for searching in tables.
(3) Compute the IDs of the triangles to the left and right of edge and store it in triangle1 index and triangle2 index .
(4) Compute the coordinate points of the left and right triangles using the triangle IDs from (3) and store it in
left triangle and right triangle
(5) Compute the coordinate points of the edges of the triangles which are not on the common edge using find point(...)
and store it in textitleft point and right point
(6) Check if edge is not Delaunay with respect to textitleft point and right point using isDelaunay(...). If False, skip
step (7). (7) If (6) is True, then edit the table of triangles to replace the two old triangles with the new ones after
performing the flip. Edit the Auxiliary Table of Edges to change the edge to the new one. Compute the four outer

10

edges of the quadrilateral in which the flip was performed. For each of the four edges, check if it is either a boundary
edge or if it already exists in the Table of Edges(toe) which are not Dealauny. If both the above conditions are
False, then add the edge to the stack Table of Edges(toe).
When the stack toe is empty, return toe aux to get the state of the grid when all edges have been made Delauny.

Figure 15: makeDelaunay(...)

11

Figure 16: makeDelaunay(...)

Contents
List of Figures

12

Figure 17: makeDelaunay(...)

4
4.1

Results
Delauny Triangulation Plots

The final Delauny Triangulation was obtained after 29911 iterations when the table of edges which are not Delauny
became empty. The plots of the final triangulation are shown below.

13

Figure 18: Final Triangulation - Delauny

Figure 19: Final Triangulation - Delauny - Zoom 1

Figure 20: Final Triangulation - Delauny - Zoom 2

Figure 21: Final Triangulation - Delauny - Zoom 3

14

Figure 22: Final Triangulation - Delauny - Zoom 4

4.2

Grid Quality Plots

The grid quality index(QI) is measured as


QI =

R0
lmin
1.0

(1)

where R0 is the circum-radius of the triangle and lm in is the minimum length of the sides of the triangle. The
R0
1.0
=
index is normalised using its value lmin
. The quality index contour plots are shown below. A value of 1
3
(blue) corresponds to an ideal triangle. Please discard the colors inside the airfoil , theyre due to some undersired
interpolation.

Figure 23: Grid Quality Index - Contours

15

Figure 24: Grid Quality Index - Contours

Figure 25: Grid Quality Index - Contours

Figure 26: Grid Quality Index - Contours

16

Figure 27: Grid Quality Index - Contours

Comments

The grid quality is seen to be slightly poor in a small location close to the leading edge, but is reasonably good
elsewhere.

Source Code

17

File: /home/athul/Dropbox/Temp/p5.py
# Author : Athul P G, athulpg007@gmail.com.
#
# Import required Python Packages
# --------------------------------------------------------------------#
import numpy as np
import matplotlib.pyplot as plt
import itertools
import copy
# --------------------------------------------------------------------#
# Load the elliptic grid coordinates from the previous project
# X_ELL and Y_ELL are matrix type text data files
# --------------------------------------------------------------------#
X=np.loadtxt('X_ELL.dat')
Y=np.loadtxt('Y_ELL.dat')
# --------------------------------------------------------------------#
# X[xi,eta] and Y[xi,eta] returns the coordinates of the grid points
# computed using the elliptic grid genertion method.
# --------------------------------------------------------------------#
def plot_grid_initial(X,Y,title):
# Plot the initial elliptic grid along with the diagonal grid lines
# as mentioned in the project directive.
# Also saves the intiial grid as png
plt.figure()
plt.hold(True)
for u in range(0,101):
plt.plot(X[u,:],Y[u,:],'r-')
for v in range(0,101):
plt.plot(X[:,v],Y[:,v],'r-')
for j in range(0,100):
for i in range(0,100):
plt.plot([X[i,j], X[i+1,j+1]], [Y[i,j], Y[i+1,j+1]],'r-')
plt.gca().set_aspect('equal')
plt.grid(True)
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Grid '+ title)
plt.savefig(title+'.png')
plt.show()
# --------------------------------------------------------------------#
# --------------------------------------------------------------------#
def create_toe():
# Creates the so called "Table of edges"
# The edges are directed from
# start point to end point
count = 0
# Stores an index value to refer to the edge later
toe
= []
# Stores all the starting and ending points
# (xi,eta) of all free edges
# Add the slant diagonal edges
for j in range(0,100):
for i in range(0,100):
toe.append([[i,j],[i+1,j+1],count])
count = count + 1
# Add the horizontal edges
for j in range(1,100):
for i in range(0,100):
toe.append([[i,j],[i+1,j],count])
count = count + 1
# Add the vertical edges
for j in range(0,100):
for i in range(1,100):

Page 1 of 7

File: /home/athul/Dropbox/Temp/p5.py
toe.append([[i,j],[i,j+1],count])
count = count + 1
return toe
# --------------------------------------------------------------------#

# --------------------------------------------------------------------#
def create_tot():
# Creates the so called "Table of Triangles"
tot = []
# Create the left-side and right side triangles of
# all the slant edges , this is sufficient to include
# all the possible triangles in the domain
# All triangles are stored in CCW direction
for j in range(0,100):
for i in range(0,100):
tot.append([[i,j],[i+1,j+1],[i,j+1]])
tot.append([[i,j],[i+1,j],[i+1,j+1]])
return tot
# --------------------------------------------------------------------#
# --------------------------------------------------------------------#
def create_toe_to_tot_map():
toe_to_tot_map = []
# Map the left and right triangles of slant diagonal edges
# The edge index is mapped to a two triangle indices # The first to the triangle on the left and the second
# to the triangle on the right
count1 = 0
for j in range(0,100):
for i in range(0,100):
toe_to_tot_map.append([count1,count1+1])
count1 = count1 + 2
# Map the left and right triangles of horizontal edges
count2 = 0
for j in range(1,100):
for i in range(0,100):
toe_to_tot_map.append([count2+201,count2])
count2 = count2 + 2
# Map the left and right triangles of vertical edges
count3 = 1
for j in range(0,100):
for i in range(1,100):
toe_to_tot_map.append([count3,count3+1])
count3 = count3 + 2
if (count3+1)%200==0:
count3=count3 + 2
# Return the TOE to TOT map
return toe_to_tot_map
# --------------------------------------------------------------------#
# --------------------------------------------------------------------#
def dist(x1,y1,x2,y2):
# Returns the distance between (x1,y1) and (x2,y2)
return np.sqrt((x2-x1)**2 + (y2-y1)**2)

Page 2 of 7

File: /home/athul/Dropbox/Temp/p5.py
# --------------------------------------------------------------------#
# --------------------------------------------------------------------#
# --------------------------------------------------------------------#
def isDelaunay(edge_point,left_point,right_point):
# Check if an edge is Delaunay
#Extract the X-coordinate of the starting and ending points of the edge
x_start = X[edge_point[0][0],edge_point[0][1]]
x_end
= X[edge_point[1][0],edge_point[1][1]]
#Extract the Y-coordinate of the starting and ending points of the edge
y_start = Y[edge_point[0][0],edge_point[0][1]]
y_end
= Y[edge_point[1][0],edge_point[1][1]]
#Compute the X and Y coordinates of the midpoint of the edge
x0 = 0.5*(x_start+x_end)
y0 = 0.5*(y_start+y_end)
#Extract the X and Y coordinates of the point to be checked on the left side
x1 = X[left_point[0],left_point[1]]
y1 = Y[left_point[0],left_point[1]]
#Extract the X and Y coordinates of the point to be checked on the right side
x2 = X[right_point[0],right_point[1]]
y2 = Y[right_point[0],right_point[1]]
#Compute the radius of the circumcircle of the edge
R = 0.5*dist(x_start,y_start,x_end,y_end)
#Compute the distance of the left and right side points from the centre of
# the circumcircle
d1 = dist(x0,y0,x1,y1)
d2 = dist(x0,y0,x2,y2)
#If both OP1 and OP2 > R , then return edge is Delaunay, return true
#else return False
if d1>R and d2>R:
return True
else:
return False
# --------------------------------------------------------------------#
# --------------------------------------------------------------------#
# --------------------------------------------------------------------#
def isBoundaryEdge(edge_point):
s1 = edge_point[0][1]==0 and edge_point[1][1]==0
s2 = edge_point[0][0]==0 and edge_point[1][0]==0
s3 = edge_point[0][1]==100 and edge_point[1][1]==100
s4 = edge_point[0][0]==100 and edge_point[1][0]==100
if s1 or s2 or s3 or s4:
return True
else:
return False
# --------------------------------------------------------------------#
# --------------------------------------------------------------------#
def isExistingEdge(edge,toe):
toe_copy=[]
for i in range(0,len(toe)):
toe_copy.append(toe[i][0:2])
if [edge[0],edge[1]] in toe_copy or [edge[1],edge[0]] in toe_copy:
return True
else:
return False
# --------------------------------------------------------------------#
# --------------------------------------------------------------------#
def find_point(edge,triangle):

Page 3 of 7

File: /home/athul/Dropbox/Temp/p5.py
# Finds the left or right point, given the edge and
# the left or right triangle correspondingly
# Delete the point in "triangle" which is
# the starting point of the edge
triangle = filter(lambda a: a != edge[0], triangle)
# Delete the point in "triangle" which is
# the ending point of the edge
triangle = filter(lambda a: a != edge[1], triangle)
# Now you're left with the only remaining point
# of the triangle which is the point to the
# left/right of the edge that needs to be
# checked for Delaunay Condition
return triangle[0]
def find_edge_index(edge,toe_aux):
toe_copy=[]
for i in range(0,len(toe_aux)):
toe_copy.append(toe_aux[i][0:2])
if [edge[0],edge[1]] in toe_copy:
flag=0
return toe_aux[toe_copy.index([edge[0],edge[1]])][2],flag
if [edge[1],edge[0]] in toe_copy:
flag=1
return toe_aux[toe_copy.index([edge[1],edge[0]])][2],flag
def plot_bounds():
plt.figure()
plt.hold(True)
for u in range(0,101):
plt.plot(X[u,0],Y[u,0],'ro')
for u in range(0,101):
plt.plot(X[u,100],Y[u,100],'ro')
for v in range(0,101):
plt.plot(X[0,v],Y[0,v],'ro')
for v in range(0,101):
plt.plot(X[100,v],Y[100,v],'ro')
plt.gca().set_aspect('equal')
plt.grid(True)
plt.xlabel('X')
plt.ylabel('Y')
plt.show()
def plot_edges(toe,tot,title):
plt.figure()
plt.hold(True)
for u in range(0,101):
plt.plot(X[u,0],Y[u,0],'k-')
for u in range(0,101):
plt.plot(X[u,100],Y[u,100],'ko')
for v in range(0,101):
plt.plot(X[0,v],Y[0,v],'ko')
for v in range(0,101):
plt.plot(X[100,v],Y[100,v],'ko')
for i in range(0,len(toe)):
#plt.plot(X[toe[i][0][0],toe[i][0][1]],Y[toe[i][0][0],toe[i][0][1]],'o')
#plt.plot(X[toe[i][1][0],toe[i][1][1]],Y[toe[i][1][0],toe[i][1][1]],'o')
x1
y1
x2
y2

=
=
=
=

X[toe[i][0][0],toe[i][0][1]]
Y[toe[i][0][0],toe[i][0][1]]
X[toe[i][1][0],toe[i][1][1]]
Y[toe[i][1][0],toe[i][1][1]]

Page 4 of 7

File: /home/athul/Dropbox/Temp/p5.py

plt.plot([x1,x2],[y1,y2],'k-')
xarr,yarr,qarr=compute_grid_metrics(tot)
plt.tricontourf(xarr,yarr,qarr,100)
cbar = plt.colorbar()
cbar.ax.set_ylabel('Grid Quality Index', rotation=270)

plt.gca().set_aspect('equal')
plt.grid(True)
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Grid : '+ title)
#plt.savefig(title+'.png')
plt.show()
def makeDelaunay(toe,tot,mapp):
toe_aux
= copy.deepcopy(toe)
# toe_aux stores the complete list of edges at every state
# of the solution. Initialised with the table of edges.
# toe_aux is updated whenever an edge is flipped
#Iteration Counter Variable
counter=1
#Continue Iterating until toe is empty
while toe:
print("Iteration : " + str(counter) + " : " + str(len(toe))+ ' Edges Left')
counter=counter+1
# Pop the first entry in the Table of Edges
edge = toe.pop(0)
# Extract the index of the edge to be used by the map
# to find the left and right triangle coordinate points.
index = edge.pop(-1)
# Use the index of the edge to find the left and right
# triangle indices which can be used to find the
# coordinates of the left and right triangle
triangle1_index
= mapp[index][0]
triangle2_index
= mapp[index][1]
left_triangle = tot[triangle1_index]
right_triangle = tot[triangle2_index]
# Compute the left and right points of the edge
# from the triangle vertices
left_point = find_point(edge,left_triangle)
right_point = find_point(edge,right_triangle)
# If the edge is not Delaunay, then
if not isDelaunay(edge,left_point,right_point):
# Edit the table of triangles to remove the old two triangles
# which are not Delaunay and add the new left and right traingles
# obtained using the flip algorithm
tot[triangle1_index] = [left_point,right_point,edge[1]]
tot[triangle2_index] = [left_point,right_point,edge[0]]
# Edit the auxilliary edge table to flip the edge at the old index
toe_aux[index] = [left_point,right_point,index]
# Add the four edges of the quadrilateral to the Table of Edges
# if they are not boundary edges and if they do not exist in the
# Table of Edges already
edge1 = [left_point,edge[1]]

Page 5 of 7

File: /home/athul/Dropbox/Temp/p5.py
edge2 = [edge[1],right_point]
edge3 = [right_point,edge[0]]
edge4 = [edge[0],left_point]
if not isExistingEdge(edge1,toe):
print("Edge 1 does not exist in Stack!")
if not isBoundaryEdge(edge1) and edge1[0][1]!=99:
index1,flag1 = find_edge_index(edge1,toe_aux)
if flag1 == 0:
toe.append([edge1[0],edge1[1],index1])
if flag1 == 1:
toe.append([edge1[1],edge1[0],index1])
if not isExistingEdge(edge2,toe):
if not isBoundaryEdge(edge2) and edge2[0][0]!=99:
index2,flag2 = find_edge_index(edge2,toe_aux)
if flag2 == 0:
toe.append([edge2[0],edge2[1],index2])
if flag2 == 1:
toe.append([edge2[1],edge2[0],index2])
if not isExistingEdge(edge3,toe):
if not isBoundaryEdge(edge3) and edge1[0][1]!=99:
index3,flag3 = find_edge_index(edge3,toe_aux)
if flag3 == 0:
toe.append([edge3[0],edge3[1],index3])
if flag3 == 1:
toe.append([edge3[1],edge3[0],index3])
if not isExistingEdge(edge4,toe):
if not isBoundaryEdge(edge4) and edge2[0][0]!=99:
index4,flag4 = find_edge_index(edge4,toe_aux)
if flag3 == 0:
toe.append([edge4[0],edge4[1],index4])
if flag3 == 1:
toe.append([edge4[1],edge4[0],index4])
return toe_aux,tot
def compute_grid_metrics(tot):
xarray=[]
yarray=[]
quality_index_array=[]
for i in range(0,len(tot)):
x1 = X[tot[i][0][0],tot[i][0][1]]
y1 = Y[tot[i][0][0],tot[i][0][1]]
x2 = X[tot[i][1][0],tot[i][1][1]]
y2 = Y[tot[i][1][0],tot[i][1][1]]
x3 = X[tot[i][2][0],tot[i][2][1]]
y3 = Y[tot[i][2][0],tot[i][2][1]]
a = dist(x1,y1,x2,y2)
b = dist(x2,y2,x3,y3)
c = dist(x3,y3,x1,y1)
s = 0.5*(a+b+c)
R0
= (a*b*c) / (4*np.sqrt(s*(s-a)*(s-b)*(s-c)))
LMIN = min(a,b,c)
qual = (R0/LMIN) / (1.0/np.sqrt(3.0))
xarray.append(x3)
yarray.append(y3)
quality_index_array.append(qual)

Page 6 of 7

File: /home/athul/Dropbox/Temp/p5.py
return xarray,yarray,quality_index_array
def main():
toe=create_toe()
tot=create_tot()
mapp=create_toe_to_tot_map()
toe_aux,tot_final=makeDelaunay(toe,tot,mapp)
return toe_aux,tot_final

Page 7 of 7