Histéresis y avalanchas

Raúl Reyes

Rodrigo Leal

Hamiltoniano

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}$$

Evolución

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.

Avalanchas

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:

  1. Buscamos el espín que inicia la avalancha, y que tiene el máximo valor de $J\sum s_j + h_i$.
  2. Incrementamos $H(t)$ a menos el valor de este campo interno, y volteamos el espín $s_i$
  3. Buscamos, entre todos los vecinos que no han sido volteados, los que tienen $J\sum s_j + h_i + H(t) = T_i > 0$, y los volteamos. Guardamos sus vecinos que no han sido volteados, y volvemos a empezar a buscar entre estos nuevos espines, hasta que ya no haya espines por voltear.
  4. Repetimos desde el paso 1.

Implementación


In [1]:
using PyPlot
using PyCall
using Interact
@pyimport matplotlib.animation as anim


INFO: Loading help data...

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).

Animaciones

Para darnos una idea de qué es lo que hace el modelo.


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]:
display_histeresis (generic function with 1 method)

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.

Distribuciones de avalanchas

Las animaciones arriba nos hacen preguntarnos cómo se ve la distribución de avalanchas al cambiar el parámetro $R$.


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]:
1-element Array{Any,1}:
 PyObject <matplotlib.lines.Line2D object at 0x11c1f3450>

Tenemos aproximadamente una recta, la distribución es exponencial efectivamente.

Curvas de histéresis

Nos interesa ahora ver el comportamiento del sistema cuando aumenta $H$, comparado con cuando disminuye.


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]:
grafica_histeresis (generic function with 1 method)

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) ;


elapsed time: 1.46551563 seconds (203510144 bytes allocated, 23.50% gc time)
elapsed time: 1.426810773 seconds (191121984 bytes allocated, 52.80% gc time)

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) ;


elapsed time: 10.076077212 seconds (364525296 bytes allocated, 7.08% gc time)
elapsed time: 10.988970668 seconds (363989948 bytes allocated, 8.37% gc time)

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) ;


elapsed time: 139.916740861 seconds (4314321480 bytes allocated, 7.64% gc time)
elapsed time: 143.447326624 seconds (4351780672 bytes allocated, 7.44% gc time)

In [30]:
grafica_histeresis(mag1,hs1,mag2,hs2,m.N,R,H_set) ;


Constatamos que:

  • La curva cuando el campo aumenta no es la misma que cuando disminuye.
  • Cuando $R$ es pequeño, hay una única avalancha grande y la magnetización aumenta bruscamente. Conforme $R$ aumenta, vemos más puntos entre el salto abrupto, hasta que obtenemos una curva continua, y con forma de S.

Sliders, sólo la subida o sólo la bajada

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 [ ]: