El sistema se modela con el modelo de Ising de campo aleatorio. El Hamiltoniano del sistema incorpora, además de la interacción de los espines vecinos, un término de la interacción de cada espín con el campo externo (que va a cambiar en el tiempo), y uno con un campo local aleatorio.
$$ H = - \sum_{\langle i, j \rangle} J s_i s_j - \sum_{i}(H(t) + h_i)s_i $$El campo aleatorio se escoge dentro de una distribución Gaussiana, con desviación estándar $R$:
$$ P(h) = \frac{1}{\sqrt{2 \pi} R} e^{-h^2/2R^2} $$Podemos reescribir al Hamiltoniano de la siguiente forma:
$$ H = - \sum_i \, \left[ \sum_{\langle j_i \rangle} J s_i s_j + (H(t) + h_i)s_i\right] $$donde usamos la notación $\langle j_i \rangle$ para referirnos a los índices de los espines que son primeros vecinos de $s_i$.
Con la suma explícita corriendo sobre el índice $i$, es claro ahora que para un espín fijo $s_i$, la contribución a la energía total del sistema es:
$$ \begin{array}{c c l} H_i & = & - s_i \, \left[J \sum_{\langle j_i \rangle} s_j + H(t) + h_i \right] \\ & = & - s_i T_i \end{array}$$Tomamos la temperatura igual a cero, y hacemos que todos los espines apunten hacia abajo. El campo externo se va a incrementar de $-\infty$ a $+\infty$, adiabáticamente (de manera infinitamente lenta), y posteriormente se va a disminuir en sentido contrario.
Originalmente todos los espines apuntan hacia abajo. El campo $H(t)$ es negativo y más grande en valor absoluto que $h_i$, (ésto es $H(t) + h_i < 0$) así que $H_i <0, \, \, \forall i$.
Empezamos a incrementar el campo externo y buscamos cuándo es más favorable energéticamente que el espín $s_i$ se voltee. Ésto ocurre cuando $T_i$ se vuelve positivo, y por lo tanto $H_i$ se vuelve positivo. Entonces, $s_i$ cambia de signo y hace que $H_i$ sea de nuevo negativo.
Cuando hacemos el camino inverso, disminuyendo el campo, $s_i$ apunta en un principio hacia arriba y ocurre lo contrario. $T_i$ originalmente es positivo, y cuando se vuelve negativo $s_i$ se voltea para hacer que $H_i$ se mantenga negativo.
El modelo que estamos utilizando da lugar de manera natural a avalanchas en las que, después de voltear un espín, a los vecinos les puede ser energeticamente favorable voltearse, sólo debido a la interacción entre espines, y con el campo externo fijo.
En el caso en que los espines apuntan para abajo, y el campo magnético externo incrementa, en la implementación del modelo tenemos que buscar al primer espín que se voltea al incrementar $H(t)$. Éste espín tiene el máximo valor de $\sum s_j + h_i$. Llevamos el campo exactamente al valor necesario para voltearlo, $H(t) = -(J\sum s_j + h_i)$, y revisamos si hay espines que se pueden voltear por la interacción entre vecinos, esto es, si se produce una avalancha. Si no se produce, o si se produce y se acaban los vecinos que se voltean, recomenzamos y buscamos un nuevo valor máximo de $J\sum s_j + h_i$
Podemos resumir el algoritmo, para propagar una avalancha:
In [1]:
using PyPlot
using PyCall
using Interact
@pyimport matplotlib.animation as anim
In [2]:
using Histeresis
La mayor parte del trabajo se ecuentra en nuestro módulo Histeresis
(histeresis.jl). En este módulo definimos al tipo MicroEstado
, a un par de funciones para crear un estado inicial y a una función que voltea a los espines. También tenemos una función que encuentra el 1er espín que se va a voltear incrementando o disminuyendo $H$, una que desarrolla una avalancha a partir de ese espín, y un par de funciones para seguir la evolución de la magnetización y de las matrices con los espines (que se van a animar).
In [3]:
function anima_histeresis(edos, nombre::ASCIIString)
fig = figure(figsize=(5,5))
cuadros = [[imshow(edos[i], interpolation="none", vmin=-1, vmax=1)] for i=1:length(edos)]
animacion = anim.ArtistAnimation(fig, cuadros, interval=200, blit=true)
animacion[:save](nombre*".mp4", extra_args=["-vcodec", "libx264", "-pix_fmt", "yuv420p"])
end
function display_histeresis(nombre::ASCIIString)
display("text/html", string("""<video autoplay controls><source src="data:video/x-m4v;base64,""",base64(open(readbytes,nombre*".mp4")),"""" type="video/mp4"></video>"""))
end
Out[3]:
In [5]:
L = 20
R = 2
espin = -1
m = edo_inicial(L,R,espin)
H_set = 15
edos = microEstados_aumenta_H!(m,H_set,espin)
anima_histeresis(edos, "L20R2") ;
Nunca logramos quitar esta imagen molesta que escupe imshow
... Abajo la animación:
In [6]:
display_histeresis("L20R2")
In [7]:
L = 20
R = 1
espin = -1
m = edo_inicial(L,R,espin)
H_set = 15
edos = microEstados_aumenta_H!(m,H_set,espin)
anima_histeresis(edos, "L20R1") ;
In [8]:
display_histeresis("L20R1")
Para $R=2$, hay una buena cantidad de avalanchas pequeñas. Para $R=1$ hay unas pequeñas al principio, y una muy grande al final que voltea todo. Esto se debe a que $R$ mide el desorden del sistema, mientras más pequeño, más se parecen todos los espines.
In [11]:
L = 50
R = 1
H_set = 15
espin = -1
m = edo_inicial(L,R,espin)
mag, hs, volteados = magnetizacion_aumenta_H!(m, H_set, espin)
M = maximum(volteados)
figure(figsize=(5,3))
title(latexstring("R=$R"))
plt.hist(volteados, M, (1, M+1));
In [12]:
L = 50
R = 2
H_set = 15
espin = -1
m = edo_inicial(L,R,espin)
mag, hs, volteados = magnetizacion_aumenta_H!(m, H_set, espin)
M = maximum(volteados)
figure(figsize=(5,3))
title(latexstring("R=$R"))
plt.hist(volteados, M, (1, M+1));
In [13]:
L = 50
R = 3
H_set = 15
espin = -1
m = edo_inicial(L,R,espin)
mag, hs, volteados = magnetizacion_aumenta_H!(m, H_set, espin)
M = maximum(volteados)
figure(figsize=(5,3))
title(latexstring("R=$R"))
plt.hist(volteados, M, (1, M+1));
In [22]:
L = 50
R = 4
H_set = 15
espin = -1
m = edo_inicial(L,R,espin)
mag, hs, volteados = magnetizacion_aumenta_H!(m, H_set, espin)
M = maximum(volteados)
figure(figsize=(5,3))
title(latexstring("R=$R"))
y, x = plt.hist(volteados, M, (1, M+1))[1:2] ;
La distribución parece tender a una distribución exponencial al incrementar $R$. Podemos hacer un cambio de variable para verificar ésto:
In [23]:
pop!(x)
figure(figsize=(5,3))
title(latexstring("R=$R"))
plot(log(y), x, "-o")
Out[23]:
Tenemos aproximadamente una recta, la distribución es exponencial efectivamente.
In [24]:
# Una función para graficar un ciclo completo, con título, nombre de ejes y leyenda
function grafica_histeresis(mag1, hs1, mag2, hs2, N, R, H_set)
figure(figsize=(7,5))
xlabel(L"H/J") #J=1
ylabel(L"M/N")
title(latexstring("R = $R"))
xlim(-H_set,H_set)
ylim(-1.3,1.8)
plot(hs1,mag1/N, ".", label="s=-1, H aumenta")
plot(hs2,mag2/N, ".", label="s=+1, H disminuye")
legend(loc="upper right")
end
Out[24]:
El ciclo es que $H$ aumenta hasta voltear todos los espines, y luego disminuye hasta voltear todos los espines.
In [25]:
L = 300
R = 0.7
espin = -1
m = edo_inicial(L,R,espin)
H_set = 5
# Empezamos con los espines apuntando hacia abajo, e incrementamos el campo H
@time mag1, hs1 = magnetizacion_aumenta_H!(m,H_set,espin)
# Espines apuntando hacia arriba, disminuye H
@time mag2, hs2 = magnetizacion_aumenta_H!(m,-H_set,-espin) ;
In [26]:
grafica_histeresis(mag1,hs1,mag2,hs2,m.N,R,H_set) ;
In [27]:
L = 300
R = 0.9
N = L^2
espin = -1
m = edo_inicial(L,R,espin)
H_set = 5
@time mag1, hs1 = magnetizacion_aumenta_H!(m,H_set,espin)
@time mag2, hs2 = magnetizacion_aumenta_H!(m,-H_set,-espin) ;
In [28]:
grafica_histeresis(mag1,hs1,mag2,hs2,m.N,R,H_set) ;
In [29]:
L = 300
R = 1.4
N = L^2
espin = -1
m = edo_inicial(L,R,espin)
H_set = 5
@time mag1, hs1 = magnetizacion_aumenta_H!(m,H_set,espin)
@time mag2, hs2 = magnetizacion_aumenta_H!(m,-H_set,-espin) ;
In [30]:
grafica_histeresis(mag1,hs1,mag2,hs2,m.N,R,H_set) ;
Constatamos que:
A continuación un ejercicio ilustrativo en el que aprovechamos el módulo Interact
para ver cómo se dibuja la curva de histéresis. Los botones +1
y -1
sirven para escoger si $H$ aumenta o disminuye respectivamente, y el slider sirve para escoger el máximo campo hasta el que se grafica.
In [ ]:
L = 50
R = 4
N = L^2
H_max = 15
fig = figure(figsize=(7,5))
xlabel(L"H/J") #J=1
ylabel(L"M/N")
@manipulate for H_set=-H_max:H_max, espin=[symbol("-1") => -1, symbol("+1") => 1]
withfig(fig) do
xlim(-H_max,H_max)
ylim(-1,1)
m = edo_inicial(L,R,espin)
mag, hs = magnetizacion_aumenta_H!(m,H_set,espin)
plot(hs,mag/N, ".")
end
end
In [ ]: