Skip to content
Snippets Groups Projects
Commit bd4007ca authored by Nicolas Mantilla Molina's avatar Nicolas Mantilla Molina
Browse files

Starting point

parent 70891995
No related branches found
No related tags found
No related merge requests found
%% Cell type:markdown id: tags:
# Fonones en Grafeno
En el presente notebook se presenta una implementación de la teoría de fonones mediante matriz dinámica en el grafeno. Se calculan las bandas de dispersión considerando primeros vecinos de una celda primitiva con dos átomos. La base de la teoría aquí presentada se encuentra en el libro de Kaxiras, E. (2019) Quantum Theory of Materials, capítulo 7.
%% Cell type:markdown id: tags:
## Análisis analítico
%% Cell type:markdown id: tags:
## Análisis numérico
%% Cell type:code id: tags:
``` python
# Importamos las librerias necesarias
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
```
%% Cell type:code id: tags:
``` python
#Definimos la matriz dinamica
def D(Kx, Ky, Kz, params):
'''
Esta función calcula la matriz dinamica de un cristal hexagonal
para un vector de onda K = (Kx, Ky, Kz). La notación de las componentes
de la matriz dinamica se puede comprender en la forma:
D_0x,0x = D_0,0, D_1x,1x = D_3,3, D_0y,1z = D_1,5, etc.
'''
#Definimos las constantes del problema
cx, cy, cz, m, a1, a2 = params
K = np.array([Kx, Ky, Kz])
dinamic = np.zeros((6,6))
dinamic[0,0] = 3*cx/m
dinamic[1,1] = 3*cy/m
dinamic[2,2] = 3*cz/m
dinamic[3,3] = 3*cx/m
dinamic[4,4] = 3*cy/m
dinamic[5,5] = 3*cz/m
dinamic[0,3] = -cx/m*(1+np.exp(-1j*np.dot(K,a1))+np.exp(-1j*np.dot(K,a2)))
dinamic[1,4] = -cy/m*(1+np.exp(-1j*np.dot(K,a1))+np.exp(-1j*np.dot(K,a2)))
dinamic[2,5] = -cz/m*(1+np.exp(-1j*np.dot(K,a1))+np.exp(-1j*np.dot(K,a2)))
dinamic[3,0] = -cx/m*(1+np.exp(1j*np.dot(K,a1))+np.exp(1j*np.dot(K,a2)))
dinamic[4,1] = -cy/m*(1+np.exp(1j*np.dot(K,a1))+np.exp(1j*np.dot(K,a2)))
dinamic[5,2] = -cz/m*(1+np.exp(1j*np.dot(K,a1))+np.exp(1j*np.dot(K,a2)))
return dinamic
#Definimos una función para calcular los valores propios de la matriz dinamica
def eigenvalues(Kx, Ky, Kz, params):
'''
Esta función calcula los valores propios de la matriz dinamica para un
vector de onda K = (Kx, Ky, Kz)
'''
dinamic = D(Kx, Ky, Kz, params)
squared = np.linalg.eigvals(dinamic)
return np.sqrt(squared)
#Definimos la función que calcula la disperción en el camino Gamma-M-K-Gamma
def dispersion(params, b1, b2):
'''
Esta función calcula la disperción en el camino Gamma-M-K-Gamma
'''
#Definimos los puntos del camino
Gamma = np.array([0,0,0])
M = b2/2
K = np.linalg.norm(b1+b2)/2*np.array([1,1/np.sqrt(3),0])
#Definimos el número de puntos en cada segmento
n = 100
#Definimos los vectores de onda en cada segmento
GM = np.array([np.linspace(Gamma[i], M[i], n) for i in range(3)])
MK = np.array([np.linspace(M[i], K[i], n) for i in range(3)])
KG = np.array([np.linspace(K[i], Gamma[i], n) for i in range(3)])
#Calculamos los valores propios en cada segmento
GM_eigenvalues = np.array([eigenvalues(GM[0,i], GM[1,i], GM[2,i], params) for i in range(n)]).T
MK_eigenvalues = np.array([eigenvalues(MK[0,i], MK[1,i], MK[2,i], params) for i in range(n)]).T
KG_eigenvalues = np.array([eigenvalues(KG[0,i], KG[1,i], KG[2,i], params) for i in range(n)]).T
#Cambiamos los nan por ceros
GM_eigenvalues = np.nan_to_num(GM_eigenvalues)
MK_eigenvalues = np.nan_to_num(MK_eigenvalues)
KG_eigenvalues = np.nan_to_num(KG_eigenvalues)
return np.array([GM_eigenvalues, MK_eigenvalues, KG_eigenvalues])
#Definimos una función para graficar la disperción en el camino Gamma-M-K-Gamma
def plot_dispersion(dispersion):
'''
Esta función grafica la disperción en el camino Gamma-M-K-Gamma
'''
#Separamos los caminos
GM = dispersion[0]
MK = dispersion[1]
KG = dispersion[2]
#Inicializamos la figura
fig = plt.figure(figsize=(10,10))
#Graficamos la disperción para cada uno de los 6 modos
colors = ['r', 'g', 'b', 'c', 'm', 'y']
for i in range(6):
plt.plot(np.linspace(0,1,100), GM[i], str(colors[i])+'.', markersize=2)
plt.plot(np.linspace(1,2,100), MK[i], str(colors[i])+'.', markersize=2)
plt.plot(np.linspace(2,3,100), KG[i], str(colors[i])+'.', markersize=2)
#Lineas verticales para separar los caminos
plt.axvline(x=1, color='k', linestyle='--')
plt.axvline(x=2, color='k', linestyle='--')
#Agregamos las etiquetas
plt.xticks([0,1,2,3], ['$\Gamma$', 'M', 'K', '$\Gamma$'])
plt.ylabel('Frecuencia (Hz)')
plt.title('Dispersión en el camino $\Gamma$-M-K-$\Gamma$')
plt.show()
```
%% Cell type:code id: tags:
``` python
disp.shape
```
%% Output
(3, 6, 100)
%% Cell type:code id: tags:
``` python
#Definimos las constantes del cristal hexagonal y los vectores de la red y de la red recíproca
a = 1 #constante de red, Angstrom
cx = 1 #constantes de resorte, N/m
cy = 1
cz = 1
m = 1 #masa, kg
a1 = np.array(a/2*np.array([np.sqrt(3),-1,0]))
a2 = np.array(a/2*np.array([np.sqrt(3),1,0]))
b1 = 2*np.pi/(a*np.sqrt(3))*np.array([1,-np.sqrt(3),0])
b2 = 2*np.pi/(a*np.sqrt(3))*np.array([1,np.sqrt(3),0])
params = [cx, cy, cz, m, a1, a2]
#Calculamos la disperción
disp = dispersion(params, b1, b2)
```
%% Output
C:\Users\nicom\AppData\Local\Temp\ipykernel_13392\234641334.py:20: ComplexWarning: Casting complex values to real discards the imaginary part
dinamic[0,3] = -cx/m*(1+np.exp(-1j*np.dot(K,a1))+np.exp(-1j*np.dot(K,a2)))
C:\Users\nicom\AppData\Local\Temp\ipykernel_13392\234641334.py:21: ComplexWarning: Casting complex values to real discards the imaginary part
dinamic[1,4] = -cy/m*(1+np.exp(-1j*np.dot(K,a1))+np.exp(-1j*np.dot(K,a2)))
C:\Users\nicom\AppData\Local\Temp\ipykernel_13392\234641334.py:22: ComplexWarning: Casting complex values to real discards the imaginary part
dinamic[2,5] = -cz/m*(1+np.exp(-1j*np.dot(K,a1))+np.exp(-1j*np.dot(K,a2)))
C:\Users\nicom\AppData\Local\Temp\ipykernel_13392\234641334.py:23: ComplexWarning: Casting complex values to real discards the imaginary part
dinamic[3,0] = -cx/m*(1+np.exp(1j*np.dot(K,a1))+np.exp(1j*np.dot(K,a2)))
C:\Users\nicom\AppData\Local\Temp\ipykernel_13392\234641334.py:24: ComplexWarning: Casting complex values to real discards the imaginary part
dinamic[4,1] = -cy/m*(1+np.exp(1j*np.dot(K,a1))+np.exp(1j*np.dot(K,a2)))
C:\Users\nicom\AppData\Local\Temp\ipykernel_13392\234641334.py:25: ComplexWarning: Casting complex values to real discards the imaginary part
dinamic[5,2] = -cz/m*(1+np.exp(1j*np.dot(K,a1))+np.exp(1j*np.dot(K,a2)))
C:\Users\nicom\AppData\Local\Temp\ipykernel_13392\234641334.py:36: RuntimeWarning: invalid value encountered in sqrt
return np.sqrt(squared)
%% Cell type:code id: tags:
``` python
#Graficamos la disperción
plot_dispersion(disp)
```
%% Output
%% Cell type:code id: tags:
``` python
plt.plot(np.linspace(0,1,100), disp[0][2])
```
%% Output
[<matplotlib.lines.Line2D at 0x24afbff0eb0>]
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment