# DataBase for some commonly used cluster

## unit-cell information

### 1D chain

• points
• $p_0 = (0, )$
• translation-vectors

• $\mathbf{a}_0 = (1, )$

• $\mathbf{b}_0 = (2\pi, )$

### square

• points
• $p_0 = (0, 0)$
• translation-vectors

• $\mathbf{a}_0 = (1, 0)$
• $\mathbf{a}_1 = (0, 1)$

• $\mathbf{b}_0 = (2\pi, 0)$

• $\mathbf{b}_1 = (0, 2\pi)$

### triangle

• points
• $p_0 = (0, 0)$
• translation-vectors

• $\mathbf{a}_0 = (1, 0)$
• $\mathbf{a}_1 = (\frac{1}{2}, \frac{\sqrt{3}}{2})$

• $\mathbf{b}_0 = (2\pi, -\frac{2\pi}{\sqrt{3}})$

• $\mathbf{b}_1 = (0, \frac{4\pi}{\sqrt{3}})$

### honeycomb

• points
• $p_0 = (0, 0)$
• $p_1 = (0, \frac{1}{\sqrt{3}})$
• translation-vectors

• $\mathbf{a}_0 = (1, 0)$
• $\mathbf{a}_1 = (\frac{1}{2}, \frac{\sqrt{3}}{2})$

• $\mathbf{b}_0 = (2\pi, -\frac{2\pi}{\sqrt{3}})$

• $\mathbf{b}_1 = (0, \frac{4\pi}{\sqrt{3}})$

### kagome

• points
• $p_0 = (0, 0)$
• $p_1 = (\frac{1}{4}, \frac{\sqrt{3}}{4})$
• $p_2 = (\frac{1}{2}, 0)$
• translation-vectors

• $\mathbf{a}_0 = (1, 0)$
• $\mathbf{a}_1 = (\frac{1}{2}, \frac{\sqrt{3}}{2})$

• $\mathbf{b}_0 = (2\pi, -\frac{2\pi}{\sqrt{3}})$

• $\mathbf{b}_1 = (0, \frac{4\pi}{\sqrt{3}})$

### cubic

• points
• $p_0 = (0, 0, 0)$
• translation-vectors

• $\mathbf{a}_0 = (1, 0, 0)$
• $\mathbf{a}_1 = (0, 1, 0)$
• $\mathbf{a}_2 = (0, 0, 1)$

• $\mathbf{b}_0 = (2\pi, 0, 0)$

• $\mathbf{b}_1 = (0, 2\pi, 0)$
• $\mathbf{b}_2 = (0, 0, 2\pi)$

## special cluster information

### square-cross

• points
• $p_0 = (0, 0)$
• $p_1 = (0, 1)$
• $p_2 = (1, 1)$
• $p_3 = (1, 2)$
• $p_4 = (2, 2)$
• $p_5 = (2, 1)$
• $p_6 = (3, 1)$
• $p_7 = (3, 0)$
• $p_8 = (2, 0)$
• $p_9 = (2, -1)$
• $p_{10} = (1, -1)$
• $p_{11} = (1, 0)$
• translation-vectors

• $\mathbf{a}_0 = (3, 2)$
• $\mathbf{a}_1 = (3, -2)$

• $\mathbf{b}_0 = (\frac{\pi}{3}, \frac{\pi}{2})$

• $\mathbf{b}_0 = (\frac{\pi}{3}, -\frac{\pi}{2})$

### square-z

• points
• $p_0 = (0, 0)$
• $p_1 = (0, 1)$
• $p_2 = (0, 2)$
• $p_3 = (1, 2)$
• $p_4 = (1, 3)$
• $p_5 = (2, 3)$
• $p_6 = (2, 2)$
• $p_7 = (2, 1)$
• $p_8 = (1, 1)$
• $p_9 = (1, 0)$
• translation-vectors

• $\mathbf{a}_0 = (3, 1)$
• $\mathbf{a}_1 = (1, -3)$

• $\mathbf{b}_0 = (\frac{3\pi}{5}, \frac{\pi}{5})$

• $\mathbf{b}_0 = (\frac{\pi}{5}, -\frac{3\pi}{5})$

### triangle-star

• points
• $p_0 = (0, 0)$
• $p_1 = (0, -\sqrt{3})$
• $p_2 = (-\frac{1}{2}, -\frac{\sqrt{3}}{2})$
• $p_3 = (-\frac{3}{2}, -\frac{\sqrt{3}}{2})$
• $p_4 = (-1, 0)$
• $p_5 = (-\frac{3}{2}, \frac{\sqrt{3}}{2})$
• $p_6 = (-\frac{1}{2}, \frac{\sqrt{3}}{2})$
• $p_7 = (0, \sqrt{3})$
• $p_8 = (\frac{1}{2}, \frac{\sqrt{3}}{2})$
• $p_9 = (\frac{3}{2}, \frac{\sqrt{3}}{2})$
• $p_{10} = (1, 0)$
• $p_{11} = (\frac{3}{2}, -\frac{\sqrt{3}}{2})$
• $p_{12} = (\frac{1}{2}, -\frac{\sqrt{3}}{2})$
• translation-vectors

• $\mathbf{a}_0 = (\frac{7}{2}, \frac{\sqrt{3}}{2})$
• $\mathbf{a}_1 = (\frac{5}{2}, -\frac{3\sqrt{3}}{2})$

• $\mathbf{b}_0 = (\frac{6\pi}{13}, \frac{10\pi}{13\sqrt{3}})$

• $\mathbf{b}_0 = (\frac{2\pi}{13}, -\frac{14\pi}{13\sqrt{3}})$

### honeycomb-benene

• points
• $p_0 = (0, 0)$
• $p_1 = (0, \frac{1}{\sqrt{3}})$
• $p_2 = (\frac{1}{2}, \frac{\sqrt{3}}{2})$
• $p_3 = (1, \frac{1}{\sqrt{3}})$
• $p_4 = (1, 0)$
• $p_5 = (\frac{1}{2}, -\frac{1}{2\sqrt{3}})$
• translation-vectors

• $\mathbf{a}_0 = (\frac{3}{2}, \frac{\sqrt{3}}{2})$
• $\mathbf{a}_1 = (\frac{3}{2}, -\frac{\sqrt{3}}{2})$

• $\mathbf{b}_0 = (\frac{2\pi}{3}, \frac{2\pi}{\sqrt{3}})$

• $\mathbf{b}_1 = (\frac{2\pi}{3}, -\frac{2\pi}{\sqrt{3}})$

### honeycomb-diphenyl

• points
• $p_0 = (0, 0)$
• $p_1 = (0, \frac{1}{\sqrt{3}})$
• $p_2 = (\frac{1}{2}, \frac{\sqrt{3}}{2})$
• $p_3 = (1, \frac{1}{\sqrt{3}})$
• $p_4 = (\frac{3}{2}, \frac{\sqrt{3}}{2})$
• $p_5 = (2, \frac{1}{\sqrt{3}})$
• $p_6 = (2, 0)$
• $p_7 = (\frac{3}{2}, -\frac{1}{2\sqrt{3}})$
• $p_8 = (1, 0)$
• $p_9 = (\frac{1}{2}, -\frac{1}{2\sqrt{3}})$
• translation-vectors

• $\mathbf{a}_0 = (\frac{5}{2}, \frac{\sqrt{3}}{2})$
• $\mathbf{a}_1 = (\frac{5}{2}, -\frac{\sqrt{3}}{2})$

• $\mathbf{b}_0 = (\frac{2\pi}{5}, \frac{2\pi}{\sqrt{3}})$

• $\mathbf{b}_1 = (\frac{2\pi}{5}, -\frac{2\pi}{\sqrt{3}})$

### honeycomb-gear

• points
• $p_0 = (0, 0)$
• $p_1 = (0, \frac{1}{\sqrt{3}})$
• $p_2 = (\frac{1}{2}, \frac{\sqrt{3}}{2})$
• $p_3 = (\frac{1}{2}, \frac{5}{2\sqrt{3}})$
• $p_4 = (1, \sqrt{3})$
• $p_5 = (\frac{3}{2}, \frac{5}{2\sqrt{3}})$
• $p_6 = (2, \sqrt{3})$
• $p_7 = (\frac{5}{2}, \frac{5}{2\sqrt{3}})$
• $p_8 = (\frac{5}{2}, \frac{\sqrt{3}}{2})$
• $p_9 = (3, \frac{1}{\sqrt{3}})$
• $p_{10} = (3, 0)$
• $p_{11} = (\frac{5}{2}, -\frac{1}{2\sqrt{3}})$
• $p_{12} = (\frac{5}{2}, -\frac{\sqrt{3}}{2})$
• $p_{13} = (2, -\frac{2}{\sqrt{3}})$
• $p_{14} = (\frac{3}{2}, -\frac{\sqrt{3}}{2})$
• $p_{15} = (1, -\frac{2}{\sqrt{3}})$
• $p_{16} = (\frac{1}{2}, -\frac{\sqrt{3}}{2})$
• $p_{17} = (\frac{1}{2}, -\frac{1}{2\sqrt{3}})$
• $p_{18} = (1, 0)$
• $p_{19} = (1, \frac{1}{\sqrt{3}})$
• $p_{20} = (\frac{3}{2}, \frac{\sqrt{3}}{2})$
• $p_{21} = (2, \frac{1}{\sqrt{3}})$
• $p_{22} = (2, 0)$
• $p_{23} = (\frac{3}{2}, -\frac{1}{2\sqrt{3}})$
• translation-vectors

• $\mathbf{a}_0 = (3, \sqrt{3})$
• $\mathbf{a}_1 = (3, -\sqrt{3})$

• $\mathbf{b}_0 = (\frac{\pi}{3}, \frac{\pi}{\sqrt{3}})$

• $\mathbf{b}_1 = (\frac{\pi}{3}, -\frac{\pi}{\sqrt{3}})$


In [1]:

from itertools import product

import matplotlib.pyplot as plt
import numpy as np




In [2]:

# database for some commonly used unit-cells

dtype = np.float64

chain_cell_info = {
"points": np.array([[0.0]], dtype=dtype),
"vectors": np.array([[1.0]], dtype=dtype)
}

square_cell_info = {
"points": np.array([[0.0, 0.0]], dtype=dtype),
"vectors": np.array([[1.0, 0.0], [0.0, 1.0]], dtype=dtype)
}

triangle_cell_info = {
"points": np.array([[0.0, 0.0]], dtype=dtype),
"vectors": np.array([[1.0, 0.0], [0.5, np.sqrt(3)/2]], dtype=dtype)
}

honeycomb_cell_info = {
"points": np.array([[0.0, 0.0], [0.0, 1/np.sqrt(3)]], dtype=dtype),
"vectors": np.array([[1.0, 0.0], [0.5, np.sqrt(3)/2]], dtype=dtype)
}

kagome_cell_info = {
"points": np.array(
[[0, 0], [0.25, np.sqrt(3)/4], [0.5, 0.0]], dtype=dtype
),
"vectors": np.array([[1, 0], [0.5, np.sqrt(3)/2]], dtype=dtype)
}

cubic_cell_info = {
"points": np.array([[0.0, 0.0, 0.0]], dtype=dtype),
"vectors": np.array(
[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]], dtype=dtype
)
}

common_cells_info = {
"chain": chain_cell_info,
"square": square_cell_info,
"triangle": triangle_cell_info,
"honeycomb": honeycomb_cell_info,
"kagome": kagome_cell_info,
"cubic": cubic_cell_info,
}




In [3]:

# database for some commonly used clusters
square_cross_info = {
"points": np.array(
[[0.0, 0.0], [0.0, 1.0], [1.0, 1.0], [1.0, 2.0],
[2.0, 2.0], [2.0, 1.0], [3.0, 1.0], [3.0, 0.0],
[2.0, 0.0], [2.0, -1.0], [1.0, -1.0], [1.0, 0.0]],
dtype=dtype
),
"vectors": np.array([[3.0, 2.0], [3.0, -2.0]], dtype=dtype)
}

square_z_info = {
"points": np.array(
[[0.0, 0.0], [0.0, 1.0], [0.0, 2.0], [1.0, 2.0], [1.0, 3.0],
[2.0, 3.0], [2.0, 2.0], [2.0, 1.0], [1.0, 1.0], [1.0, 0.0]],
dtype=dtype
),
"vectors": np.array([[3.0, 1.0], [1.0, -3.0]], dtype=dtype)
}

triangle_star_info = {
"points": np.array(
[[0.0, 0.0],
[0.0, -np.sqrt(3)], [-0.5, -np.sqrt(3)/2], [-1.5, -np.sqrt(3)/2],
[-1.0, 0.0], [-1.5, np.sqrt(3)/2], [-0.5, np.sqrt(3)/2],
[0.0, np.sqrt(3)], [0.5, np.sqrt(3)/2], [1.5, np.sqrt(3)/2],
[1.0, 0.0], [1.5, -np.sqrt(3)/2], [0.5, -np.sqrt(3)/2]],
dtype=dtype
),
"vectors": np.array(
[[3.5, np.sqrt(3)/2], [2.5, -1.5*np.sqrt(3)]], dtype=dtype
)
}

honeycomb_benzene_info = {
"points": np.array(
[[0.0, 0.0], [0.0, 1/np.sqrt(3)], [0.5, np.sqrt(3)/2],
[1.0, 1/np.sqrt(3)], [1.0, 0.0], [0.5, -0.5/np.sqrt(3)]],
dtype=dtype
),
"vectors": np.array(
[[1.5, np.sqrt(3)/2], [1.5, -np.sqrt(3)/2]], dtype=dtype
)
}

honeycomb_diphenyl_info = {
"points": np.array(
[[0.0, 0.0], [0.0, 1/np.sqrt(3)], [0.5, np.sqrt(3)/2],
[1.0, 1/np.sqrt(3)], [1.5, np.sqrt(3)/2], [2.0, 1/np.sqrt(3)],
[2.0, 0.0], [1.5, -0.5/np.sqrt(3)], [1.0, 0.0],
[0.5, -0.5/np.sqrt(3)]],
dtype=dtype
),
"vectors": np.array(
[[2.5, np.sqrt(3)/2], [2.5, -np.sqrt(3)/2]], dtype=dtype
)
}

honeycomb_gear_info = {
"points": np.array(
[[0.0, 0.0], [0.0, 1/np.sqrt(3)], [0.5, np.sqrt(3)/2],
[0.5, 2.5/np.sqrt(3)], [1.0, np.sqrt(3)], [1.5, 2.5/np.sqrt(3)],
[2.0, np.sqrt(3)], [2.5, 2.5/np.sqrt(3)], [2.5, np.sqrt(3)/2],
[3.0, 1/np.sqrt(3)], [3.0, 0.0], [2.5, -0.5/np.sqrt(3)],
[2.5, -np.sqrt(3)/2], [2.0, -2/np.sqrt(3)], [1.5, -np.sqrt(3)/2],
[1.0, -2/np.sqrt(3)], [0.5, -np.sqrt(3)/2], [0.5, -0.5/np.sqrt(3)],
[1.0, 0.0], [1.0, 1/np.sqrt(3)], [1.5, np.sqrt(3)/2],
[2.0, 1/np.sqrt(3)], [2.0, 0.0], [1.5, -0.5/np.sqrt(3)]],
dtype=dtype
),
"vectors": np.array([[3, np.sqrt(3)], [3, -np.sqrt(3)]], dtype=dtype)
}

special_clusters_info = {
"square_cross": square_cross_info,
"square_12": square_cross_info,
"cross": square_cross_info,

"square_z": square_z_info,
"square_10": square_z_info,
"z": square_z_info,

"triangle_star": triangle_star_info,
"triangle_13": triangle_star_info,
"star": triangle_star_info,

"honeycomb_benzene": honeycomb_benzene_info,
"honeycomb_6": honeycomb_benzene_info,
"benzene": honeycomb_benzene_info,

"honeycomb_diphenyl": honeycomb_diphenyl_info,
"honeycomb_10": honeycomb_diphenyl_info,
"diphenyl": honeycomb_diphenyl_info,

"honeycomb_gear": honeycomb_gear_info,
"honeycomb_24": honeycomb_gear_info,
"gear": honeycomb_gear_info,
}




In [4]:

def special_cluster(which):
"""
Generating some special cluster

Parameters
----------
which : str
Which special lattice to generate
Currently supported special lattice:
"square_cross" | "square_z" | "triangle_star" |
"honeycomb_benzene" | "honeycomb_diphenyl" | "honeycomb_gear"
Alias:
"square_cross" | "square_12" | "cross";
"square_z" | "square_10" | "z";
"triangle_star" | "triangle_13" | "star";
"honeycomb_benzene" | "honeycomb_6"| "benzene";
"honeycomb_diphenyl" | "honeycomb_10" | "diphenyl";
"honeycomb_gear" | "honeycomb_24" | "gear"

Returns
-------
points : ndarray
The coordinates of the points in the cluster
vectors : ndarray
The translation vectors of the cluster
"""

try:
cluster_info = special_clusters_info[which]
return cluster_info["points"], cluster_info["vectors"]
except KeyError:
raise KeyError("Unrecognized special lattice name!")

def lattice_generator(which, num0=1, num1=1, num2=1):
"""
Generating a common cluster with translation symmetry

Parameters
----------
which : str
Which  type of lattice to generate.
Legal value:
"chain" | "square" | "triangle" | "honeycomb" | "kagome" | "cubic"
num0 : int, optional
The number of unit cell along the first translation vector
default: 1
num1 : int, optional
The number of unit cell along the second translation vector. It only
takes effect for 2D and 3D lattice.
default: 1
num2 : int, optional
The number of unit cell along the second translation vector. It only
takes effect for 3D lattice.
default : 1

Returns
-------
points : ndarray
The coordinates of the points in the cluster
vectors : ndarray
The translation vectors of the cluster
"""

assert isinstance(num0, int) and num0 >= 1
assert isinstance(num1, int) and num1 >= 1
assert isinstance(num2, int) and num2 >= 1

try:
cell_info = common_cells_info[which]
cell_points = cell_info["points"]
cell_vectors = cell_info["vectors"]
except KeyError:
raise KeyError("Unrecognized lattice type!")

if which == "chain":
if num0 == 1:
return cell_points, cell_vectors
else:
vectors = cell_vectors * np.array([[num0]])
mesh = product(range(num0))
elif which == "cubic":
if num0 == 1 and num1 == 1 and num2 == 1:
return cell_points, cell_vectors
else:
vectors = cell_vectors * np.array([[num0], [num1], [num2]])
mesh = product(range(num0), range(num1), range(num2))
else:
if num0 == 1 and num1 == 1:
return cell_points, cell_vectors
else:
vectors = cell_vectors * np.array([[num0], [num1]])
mesh = product(range(num0), range(num1))

dim = cell_points.shape[1]
dRs = np.matmul(list(mesh), cell_vectors)
points = np.reshape(dRs[:, np.newaxis, :] + cell_points, newshape=(-1, dim))

return points, vectors

def show(points, vectors, scope=0):
"""
Plot the given points

Parameter
---------
points : ndarray
The coordinates of the points
vectors : ndarray
The trnaslation vectors of the cluster
scope : int, optional
Determine the number of cluster to draw
default: 0
"""

assert isinstance(points, np.ndarray) and points.ndim == 2
assert isinstance(vectors, np.ndarray) and vectors.ndim == 2
assert isinstance(scope, int) and scope >= 0

point_num, space_dim = points.shape
trans_dim, tmp = vectors.shape
if space_dim > 2:
raise ValueError("Not supported space dimension!")

if trans_dim > space_dim:
raise ValueError("The number of translation vectors should be no more than the space dimension!")

if tmp != space_dim:
raise ValueError("The translation vectors should have the same space dimension as the points!")

clusters = [
points + np.matmul(tmp, vectors)
for tmp in product(range(-scope, scope+1), repeat=trans_dim)
]

fig, ax = plt.subplots()
fig.set_size_inches((16, 9))
ax.set_axis_off()
ax.set_aspect("equal")

if space_dim == 1:
ys = np.zeros(shape=points.shape)
for cluster in clusters:
ax.plot(cluster, ys, marker="o", ls="None", ms=8)
else:
for cluster in clusters:
ax.plot(cluster[:, 0], cluster[:, 1], marker="o", ls="None", ms=8)

left, right = ax.get_xlim()
bottom, top = ax.get_ylim()
half = max(right - left, top - bottom) / 2
x_center = (right + left) / 2
y_center = (top + bottom) / 2
ax.set_xlim(left=x_center-half, right=x_center+half)
ax.set_ylim(bottom=y_center-half, top=y_center+half)
plt.show()




In [5]:

show(*special_cluster("square_cross"), scope=1)







In [6]:

show(*special_cluster("square_z"), scope=1)







In [7]:

show(*special_cluster("triangle_star"), scope=1)







In [8]:

show(*special_cluster("honeycomb_benzene"), scope=1)







In [9]:

show(*special_cluster("honeycomb_diphenyl"), scope=1)







In [10]:

show(*special_cluster("honeycomb_gear"), scope=1)







In [11]:

num = 4
show(*lattice_generator("chain", num0=num), scope=1)







In [12]:

show(*lattice_generator("square", num0=num, num1=num), scope=1)







In [13]:

show(*lattice_generator("triangle", num0=num, num1=num), scope=1)







In [14]:

show(*lattice_generator("honeycomb", num0=num, num1=num), scope=1)







In [15]:

show(*lattice_generator("kagome", num0=num, num1=num), scope=1)