In [1]:
matplotlib inline
In [8]:
from numpy import *
from matplotlib import *
from matplotlib.pyplot import *
In [132]:
#todo:
#now make these drawings for the 
#hexagon on diagonal multiplied by [1, 1.21, 1.31, 1.46]
#and the other way, turned 90 degrees and multiplied by [1, 0.83, 0.75, 0.69]
#and squeezed in one way

def rot(rotation):
    al=rotation*2*pi/360
    return np.array([[cos(al), sin(al)],[-sin(al), cos(al)]]).T

def unit_cell_matrix(a, rotation, extension_faction_11):
    hexagonal_cell = np.array([[a, 0], [-a/2, a*sqrt(3)/2]])
    rotated = np.dot(hexagonal_cell, rot(-rotation))

    extension_11 = np.dot(rot(45), np.dot([[extension_faction_11,0],[0,1]], rot(-45).T))
    return np.dot(rotated, extension_11)


#parameters of the unit cell: a, rotation angle, extension along diagonal
params = [[a, 15, 1],
          [1.21*a, 15, 1.1],
          [1.31*a, 15, 1.1],
          [1.46*a, 15, 1.1],
          [a, -15, 1],
          [0.9*a, -15, 1/1.1],
          [0.8*a, -15, 1/1.1],
          [0.7*a, -15, 1/1.1]]

param=params[0]
In [137]:
import numpy as np
from numpy.linalg import norm
from numpy.fft import fft2, fftshift
import matplotlib.pyplot as plt

def gaussian_2d(x, y, sigma=1.0):
    return np.exp(-(x**2 + y**2)/(2*sigma**2))

def draw_cell(cell, drawing_no):
    # Parameters
    N = 1024  # image size
    a = 32   # lattice constant
    r = 5    # atom radius
    sigma_atom = 0.0  # atom gaussian width
    sigma_window = N/8  # window function width
    
    # cell = np.array([[a, 0],[-a/2, a]])
    
    # Create coordinate grids
    x = np.linspace(-N/2, N/2, N)
    y = np.linspace(-N/2, N/2, N)
    X, Y = np.meshgrid(x, y)
    
    # Initialize image
    image = np.zeros((N, N))
    
    # Generate hexagonal lattice positions with random displacements
    n_cells = N//a
    for i in range(-n_cells//2, n_cells//2):
        for j in range(-n_cells//2, n_cells//2):
            x_pos,y_pos = dot(cell.T, [i,j])
            
            # Add random displacement
            dx = np.random.normal(0, sigma_atom)
            dy = np.random.normal(0, sigma_atom)
            
            # Add gaussian at each lattice point
            image += gaussian_2d(X - (x_pos + dx), Y - (y_pos + dy), r)
    
    # Apply window function. This removes ugly artifacts which arrise due to trunctation on the edge of the reconstructed plane
    window = gaussian_2d(X, Y, sigma_window)
    image *= window
    
    # Calculate Fourier transform
    ft = fftshift(np.abs(fft2(image)))
    
    # Plot results
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(11, 5))

    
    ax1.imshow(image>0.6*amax(image), cmap=cm.Greys, extent=[-N/2,N/2-1,-N/2,N/2-1])
    ax1.set_title('Real Space')
    ax1.axis('equal')
    rlim = 80
    ax1.axis([-rlim,rlim,-rlim,rlim])
    
    clim = amax(ft)/3
    ax2.imshow(ft, cmap=cm.Greys_r, extent=[-N/2,N/2-1,-N/2,N/2-1], clim=[0,clim])
    
    lim = 80
    
    ax2.axis('equal')
    ax2.axis([-lim,lim,-lim,lim])
    
    ax2.set_title('Fourier Transform')
    
    for ax in [ax1,ax2]:
        ax.set_xticks([])
        ax.set_yticks([])

    savefig(f"drawing_{drawing_no}.png")


for i,param in list(enumerate(params)):
    cell = unit_cell_matrix(*param)
    draw_cell(cell, i)
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
In [ ]: