Created
May 16, 2011 07:20
-
-
Save shoke/974032 to your computer and use it in GitHub Desktop.
Graphene
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import networkx as nx | |
import matplotlib as mat | |
import matplotlib.pyplot as plt | |
import numpy as np | |
# Colors each node in the given graph based on the data | |
# Set provided | |
def color_graph(graph, d, cmap): | |
col_graph = nx.Graph() | |
#normalize the data and create an array of colors that will | |
#correspond to the nodes in the graph | |
data = (normalize(d)) | |
color_array = [] | |
for j in range(len(data)): | |
color = cmap(data[j]) | |
color_array.append( color ) | |
i = 0 | |
# add the color to each node | |
for node in graph.nodes(): | |
red = int(255*color_array[i][0]) | |
blu = int(255*color_array[i][1]) | |
gre = int(255*color_array[i][2]) | |
alp = color_array[i][3] | |
i = i + 1 | |
col_graph.add_node(node,{'viz':{'color':dict(r=red,b=blu,g=gre,a=alp)}}) | |
col_graph.add_edges_from(graph.edges()) | |
return col_graph | |
# Normalizes the given data between 0 and 1 | |
def normalize(data): | |
d = [] | |
min = float(np.min(data)) | |
max = float(np.max(data)) | |
data_range = max - min | |
for j in range(len(data)): | |
d.append( ( float(data[j]) - min) / data_range ) | |
return d | |
# Utilizes the networkx draw_networkx function | |
# Useful for small graphs | |
def graphene_graph(g, data, cmap = plt.cm.Blues): | |
min = float(np.min(data)) | |
max = float(np.max(data)) | |
nx.draw_networkx(g, cmap = cmap, vmin = min, vmax = max, node_color = data) | |
plt.show() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import networkx as nx | |
import matplotlib as mat | |
import matplotlib.pyplot as plt | |
import colorgraph | |
# Builds a graphene sheet with the given number of rows and columns. | |
# If wrap is set to true it will roll it up | |
def build_graph(rows, columns, wrap): | |
g = nx.Graph() | |
# creates the first complete hexagon | |
for i in range(6): | |
if (i+1) > 1: | |
g.add_edge(i+1,i) | |
g.add_edge(6,1) | |
# top of the first hexagon, start and end of the next hexagon | |
start = 4 | |
end = 5 | |
numNodes = 6 | |
# if the number of hexagons in the row is greater than 1 | |
if rows > 1: | |
for j in range(rows-1): | |
s = start | |
# 2 nodes already placed, adds the next 4 | |
for addnodes in range(4): | |
g.add_edge(s, numNodes+1) | |
numNodes += 1 | |
s = numNodes | |
g.add_edge(numNodes, end) | |
start += 4 | |
end += 4 | |
evenColumn = True | |
secondColumn = True | |
connection = 1 | |
# startingNode is the node the NEXT column will start at | |
# (aka the bottom of the one being drawn) | |
startingNode = numNodes + 1 | |
# start is your current postion | |
start = startingNode | |
# if there is more than one column | |
if columns > 1: | |
for k in range(columns-1): | |
# even vs. odd columns start and end differently | |
if evenColumn: | |
# the connection to the last finished column | |
# the first hexagon in each new column has one extra node | |
connection += 2 | |
if not(k == (columns-2)): | |
g.add_edge(start, start+1) | |
start += 1 | |
numNodes +=1 | |
g.add_edge(start, start+1) | |
g.add_edge(start, connection) | |
numNodes += 1 | |
for l in range(rows -1): | |
# the second column is a special case | |
if secondColumn: | |
connection += 4 | |
else: | |
connection += 2 | |
start += 1 | |
g.add_edge(start-1, start) | |
g.add_edge(start, start+1) | |
start += 1 | |
g.add_edge(start, connection) | |
numNodes += 2 | |
# finish column | |
if not(k == (columns-2)): | |
g.add_edge(numNodes , numNodes +1) | |
numNodes +=1 | |
evenColumn = False | |
secondColumn = False | |
connection = startingNode | |
startingNode = numNodes | |
start = numNodes +1 | |
else: | |
g.add_edge(start, connection) | |
g.add_edge(start, start+1) | |
start += 1 | |
g.add_edge(start, start+1) | |
start += 1 | |
connection += 2 | |
g.add_edge(start, connection) | |
numNodes += 3 | |
for l in range(rows -1): | |
connection += 2 | |
g.add_edge(start+1, start) | |
start += 1 | |
g.add_edge(start, start+1) | |
start += 1 | |
g.add_edge(start, connection) | |
numNodes += 2 | |
# finish column | |
start += 1 | |
evenColumn = True | |
connection = startingNode | |
startingNode = start | |
# are we rolling the sheet? | |
if wrap and (rows > 0): | |
g.remove_node( 2 + (rows * 4) - 1 ) | |
g.add_edge( 2 + (rows * 4) , 1 ) | |
g.remove_node( 2 + (rows * 4) - 2 ) | |
g.add_edge( 2 + (rows * 4) - 3, 2 ) | |
start = 3 + (rows * 4) | |
for k in range(columns-1): | |
end = 2 * rows + start | |
g.remove_node( end ) | |
g.add_edge( end - 1, start ) | |
start = end + 1 | |
return g | |
def build_and_color(rows,columns,wrap,data,cmap = plt.cm.Blues, filename = "test.gexf"): | |
g = build_graph(rows,columns,wrap) | |
g = colorgraph.color_graph(g,data,cmap) | |
nx.write_gexf(g,filename) | |
# Builds a graphene sheet with the given number of rows and columns. | |
# The sheet has a defected column running through the optionally passed | |
# arg. Otherwise it defaults to the center. | |
def defected_graphene_graph(rows, columns, defect = 0): | |
g = nx.Graph() | |
index = 0; | |
if( columns <= 2 ): | |
print "Must have more than two columns." | |
return g | |
if( rows < 2 ): | |
print "Must have more than 1 row." | |
return g | |
if defect[index] == 1: | |
print "Defect wire cannot be on edge column." | |
if defect[index] == columns: | |
print "Defect wire cannot be on edge column." | |
if (defect[index] == 0) : | |
defect[index] = int(columns/2) + 1 | |
# creates the first complete hexagon | |
for i in range(6): | |
if (i+1) > 1: | |
g.add_edge(i+1,i) | |
g.add_edge(6,1) | |
# top of the first hexagon, start and end of the next hexagon | |
start = 4 | |
end = 5 | |
numNodes = 6 | |
# if the number of hexagons in the row is greater than 1 | |
if rows > 1: | |
for j in range(rows-1): | |
s = start | |
# 2 nodes already placed, adds the next 4 | |
for addnodes in range(4): | |
g.add_edge(s, numNodes+1) | |
s = numNodes + 1 | |
numNodes += 1 | |
g.add_edge(numNodes, end) | |
start += 4 | |
end += 4 | |
evenColumn = True | |
secondColumn = True | |
connection = 1 | |
# startingNode is the node the NEXT column will start at | |
# (aka the bottom of the one being drawn) | |
startingNode = numNodes + 1 | |
# start is your current postion | |
start = startingNode | |
afterDefect = False | |
after2 = False | |
# if there is more than one column | |
if columns > 1: | |
for k in range(columns-1): | |
if( k+2 == defect[index] ): | |
if evenColumn: | |
connection += 2 | |
g.add_edge(connection, start) | |
g.add_edge(start, start+1) | |
g.add_edge(start+1, start+2) | |
g.add_edge(start+1, start+2) | |
g.add_edge(start+2, start+3) | |
g.add_edge(start+3, start+4) | |
numNodes += 5 | |
# the second column is a special case | |
if secondColumn: | |
connection += 4 | |
else: | |
connection += 2 | |
g.add_edge(connection, start+4) | |
start += 4 | |
evenRow = True | |
for l in range(rows -2): | |
if evenRow: | |
# the second column is a special case | |
if secondColumn: | |
connection += 4 | |
elif afterDefect: | |
connection += 4 | |
else: | |
connection += 2 | |
g.add_edge(start, start+1) | |
g.add_edge(start+1, connection) | |
start = start -1 | |
g.add_edge(start, start+3) | |
g.add_edge(start+3, start + 4) | |
g.add_edge(start+2, start + 4) | |
start += 4 | |
numNodes += 3 | |
evenRow = False | |
else: | |
# the second column is a special case | |
if secondColumn: | |
connection += 4 | |
else: | |
connection += 2 | |
g.add_edge(start, start+1) | |
g.add_edge(start+2, start+1) | |
g.add_edge(start+2, start+3) | |
g.add_edge(connection, start+3) | |
numNodes += 3 | |
start += 3 | |
evenRow = True | |
if not evenColumn: | |
if evenRow: | |
# the second column is a special case | |
if secondColumn: | |
connection += 4 | |
else: | |
connection += 2 | |
g.add_edge(start, start+1) | |
if not afterDefect: | |
g.add_edge(start+1, connection) | |
start = start -1 | |
g.add_edge(start, start+3) | |
g.add_edge(start+3, start + 4) | |
g.add_edge(start+2, start + 4) | |
start += 2 | |
if afterDefect: | |
g.add_edge(start, start+3) | |
g.add_edge(start+3, start+4) | |
g.add_edge(start+4, connection-2) | |
start += 2 | |
numNodes += 5 | |
evenRow = False | |
else: | |
connection += 2 | |
g.add_edge(start, start+1) | |
start += 1 | |
g.add_edge(start, start+1) | |
start += 1 | |
g.add_edge(start, start+1) | |
start += 1 | |
g.add_edge(start, connection) | |
numNodes += 3 | |
connection = startingNode + 1 | |
start = numNodes +1 | |
evenColumn = not evenColumn | |
startingNode = numNodes | |
secondColumn = False | |
afterDefect = True | |
if not(index == (len(defect)-1)): | |
index = index + 1 | |
# even vs. odd columns start and end differently | |
elif evenColumn: | |
# the connection to the last finished column | |
# the first hexagon in each new column has one extra node | |
connection += 2 | |
if not(k == (columns-2)): | |
g.add_edge(start, start+1) | |
start += 1 | |
numNodes +=1 | |
g.add_edge(start, start+1) | |
if afterDefect: | |
#connection += 1 | |
evenRow = True | |
g.add_edge(start, connection) | |
numNodes += 1 | |
for l in range(rows -1): | |
# the second column is a special case | |
if secondColumn: | |
connection += 4 | |
elif afterDefect: | |
if evenRow: | |
connection += 4 | |
evenRow = False | |
else: | |
connection += 2 | |
evenRow = True | |
else: | |
connection += 2 | |
start += 1 | |
g.add_edge(start-1, start) | |
g.add_edge(start, start+1) | |
start += 1 | |
g.add_edge(start, connection) | |
numNodes += 2 | |
# finish column | |
if not(k == (columns-2)): | |
g.add_edge(numNodes , numNodes +1) | |
numNodes +=1 | |
evenColumn = False | |
secondColumn = False | |
connection = startingNode | |
if afterDefect: | |
connection += 1 | |
elif after2: | |
g.add_edge(numNodes, numNodes + 1) | |
numNodes += 1 | |
startingNode = numNodes | |
start = numNodes +1 | |
afterDefect = False | |
else: | |
g.add_edge(start, connection) | |
g.add_edge(start, start+1) | |
start += 1 | |
g.add_edge(start, start+1) | |
start += 1 | |
if afterDefect: | |
g.add_edge(start, start+1) | |
start += 1 | |
connection += 1 | |
evenRow = True | |
else: | |
connection += 2 | |
g.add_edge(start, connection) | |
numNodes += 3 | |
for l in range(rows -1): | |
if afterDefect: | |
if evenRow: | |
connection += 4 | |
evenRow = False | |
else: | |
connection += 2 | |
evenRow = True | |
else: | |
connection += 2 | |
g.add_edge(start+1, start) | |
start += 1 | |
g.add_edge(start, start+1) | |
start += 1 | |
if( l == (rows-2) ): | |
if afterDefect: | |
g.add_edge(start +1, start) | |
if evenRow: | |
g.add_edge(start +1, connection-1) | |
else: | |
g.add_edge(start +1, connection-3) | |
numNodes += 3 | |
else: | |
g.add_edge(start, connection) | |
numNodes += 2 | |
else: | |
g.add_edge(start, connection) | |
numNodes += 2 | |
# finish column | |
start += 1 | |
evenColumn = True | |
if after2: | |
after2 = False | |
if afterDefect: | |
startingNode += 1 | |
after2 = True | |
start += 1 | |
connection = startingNode | |
startingNode = start | |
afterDefect = False | |
return g |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import networkx as nx | |
import random | |
# Adds the number of defects specified to the graph. Removes the nodes randomly | |
# and all adjacent edges | |
def add_defects(graph, number): | |
# do we have enough nodes? | |
if (number >= len(graph.nodes()) ): | |
print "The number of defects must be less than the size of the graph" | |
return graph | |
# randomly generate nodes to pull | |
defects = random.sample(graph.nodes(), number) | |
for i in range(len(defects)): | |
graph.remove_node(defects[i]) | |
return graph | |
def stonewales_defect(graph, node): | |
neighbors = graph.neighbors(node) | |
new_graph = graph | |
node2 = 0 | |
if neighbors[0] < node: | |
if neighbors[1] < node: | |
node2 = node-1 | |
elif neighbors[2] < node: | |
node2 = node-1 | |
else: | |
node2 = node | |
node = node+1 | |
elif neighbors[0] > node: | |
if neighbors[1] > node: | |
node2 = node | |
node = node+1 | |
elif neighbors[2] > node: | |
node2 = node | |
node = node+1 | |
else: | |
node2 = node-1 | |
if(len(graph.neighbors(node)) < 3): | |
print "Bad node" | |
return graph | |
if(len(graph.neighbors(node2)) < 3): | |
print "Bad node" | |
return graph | |
new_graph.remove_edge(node, node+1) | |
new_graph.remove_edge(node, node-1) | |
new_graph.add_edge(node,node-2) | |
new_graph.remove_edge(node2, node2-1) | |
new_graph.add_edge(node2,node2+2) | |
new_graph.add_edge(node,node2) | |
return new_graph | |
# Builds a complete two-node graph | |
def build_two_node(): | |
return nx.complete_graph(2) | |
# Builds a complete three-node graph | |
def build_three_node(): | |
return nx.complete_graph(3) | |
# Builds a complete four-node graph | |
def build_four_node(): | |
return nx.complete_graph(4) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import networkx as nx | |
def get_hamiltonian(g): | |
return -0.5 * nx.laplacian(g) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
OK, great start. As a next step, let's put the main part of the code in a python function that takes the input parameters (rows, columns) and returns a networkx graph object. After that, I think we want to begin to work on characterizing the sheet using the lattice unit vectors a_1 and a_2. These provide a very powerful and exact way of describing any sheet of graphene (or nanotube). A good starting point for learning about this is the Wikipedia page on Carbon Nanotubes: http://en.wikipedia.org/wiki/Carbon_nanotube
I will have research office hours this Wed and we can talk more about this then.