-
Notifications
You must be signed in to change notification settings - Fork 0
/
tight_binding.py
100 lines (77 loc) · 3.45 KB
/
tight_binding.py
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import random
import numpy as np
import matplotlib.pyplot as plt
def calcular_estructura_de_bandas(N, a, t, eps, valores_k):
"""
Calcula la estructura de bandas para un modelo de tight-binding en 1D.
Parámetros:
N (int): Número de orbitales atómicos.
a (float): Espaciado de la red.
t (float): Parámetro de hopping.
eps (float): Energía en el sitio.
valores_k (np.ndarray): Array de valores de k.
Retorna:
lista de np.ndarray: Lista de arrays de autovalores para cada valor de k.
"""
autovalores = []
for k in valores_k:
H = np.zeros((N, N), dtype=complex)
# Término de energía en el sitio
for i in range(N):
H[i, i] = eps
# Términos de hopping con condiciones de contorno periódicas
for i in range(N):
H[i, (i+1) % N] = -t * np.exp(1j * k * a)
H[(i+1) % N, i] = -t * np.exp(-1j * k * a)
evals = np.linalg.eigvalsh(H)
autovalores.append(evals)
return autovalores
def seleccionar_autovalores_aleatorios(autovalores):
"""
Selecciona un conjunto arbitrario de autovalores de la estructura de bandas calculada.
Parámetros:
autovalores (lista de np.ndarray): Lista de arrays de autovalores para cada valor de k.
Retorna:
np.ndarray: Array de autovalores seleccionados.
"""
indice_aleatorio = random.randint(0, len(autovalores) - 1)
return autovalores[indice_aleatorio]
def aplicar_condiciones_de_contorno_periodicas(autovalores):
"""
Aplica condiciones de contorno periódicas de manera que E(-k) = E(k).
Parámetros:
autovalores (np.ndarray): Array de autovalores.
Retorna:
np.ndarray: Array de autovalores con condiciones de contorno periódicas aplicadas.
"""
return np.concatenate((np.flip(autovalores, 0), autovalores), axis=0)
def calcular_banda_analitica(valores_k, t, eps, a):
return eps - 2 * t * np.cos(valores_k * a)
def graficar_estructura_de_bandas(valores_k, banda_numerica, t, eps, a, N):
banda_analitica = calcular_banda_analitica(valores_k, t, eps, a)
fig, axs = plt.subplots()
axs.plot(valores_k, banda_numerica, 'o', label=f'Autovalores de H(k)')
axs.plot(valores_k, banda_analitica, label=r'$E(k) = \epsilon_0 - 2t\cos(ka)$', linestyle='--', color='black')
axs.set_yticks([eps-2.*t, eps-t, eps, eps+t, eps+2.*t])
axs.set_yticklabels(['$\epsilon_0-2t$', '$\epsilon_0-t$', '$\epsilon_0$', '$\epsilon_0+t$', '$\epsilon_0+2t$'])
axs.set_xlabel('k')
axs.set_ylabel('E(k)')
axs.set_title(f'Modelo de tight-binding con cadena atómica de N={N} celdas')
axs.legend()
axs.grid(True)
fig.savefig('tight_binding.png')
# Parámetros
N = 50 # Número de orbitales atómicos
a = 1 # Espaciado de la red
t = 0.5 # Parámetro de hopping
eps = 0.0 # Energía en el sitio
max_iterations = 2 * N
valores_k = np.linspace(-np.pi/a, np.pi/a, max_iterations) # Array de valores k
# Calcular la estructura de bandas
autovalores = calcular_estructura_de_bandas(N, a, t, eps, valores_k)
# Seleccionar un conjunto arbitrario de autovalores para graficar
autovalores_seleccionados = seleccionar_autovalores_aleatorios(autovalores)
# Aplicar las condiciones de contorno periódicas
autovalores_con_ccp = aplicar_condiciones_de_contorno_periodicas(autovalores_seleccionados)
# Graficar la estructura de bandas
graficar_estructura_de_bandas(valores_k, autovalores_con_ccp, t, eps, a, N)