我正在尝试计算 NiO 的 Ising 模型。由于 O 没有磁矩,我只需要考虑 Ni 的情况,它需要第二近邻 Ising 模型。如下图所示,Ni 原子以耦合常数 J1 = 2.3 meV 与其最近邻原子相互作用,以耦合常数 J2 = -21 meV 与其第二近邻原子相互作用。
我创建了一些代码,该代码生成一个矩阵,该矩阵在每个第二个条目中交替 1 和 -1(向上/向下旋转),在每个其他条目(代表氧气)中交替出现 0。我还定义了将翻转每个最近邻居和第二最近邻居的旋转的函数。由于主要的耦合常数 J2 < 0,系统应该是反铁磁的,因此自旋应该对角对齐,重复图案 (1,0,-1,0),例如:
[ 0 -1 0 1 0 -1 0 1 0 -1]
[ 1 0 -1 0 1 0 -1 0 1 0]
[ 0 1 0 -1 0 1 0 -1 0 1]
[-1 0 1 0 -1 0 1 0 -1 0]
[ 0 -1 0 1 0 -1 0 1 0 -1]
[ 1 0 -1 0 1 0 -1 0 1 0]
[ 0 1 0 -1 0 1 0 -1 0 1]
[-1 0 1 0 -1 0 1 0 -1 0]
[ 0 -1 0 1 0 -1 0 1 0 -1]
[ 1 0 -1 0 1 0 -1 0 1 0]
但是,当我运行代码时,我无法做到这一点。我可以在低温(T~2)下达到一定数量的顺序,但不能达到如下所示的全铁磁性。走低(例如 T~0.01)会产生无序:
这是我的代码:
#!/usr/bin/env python
import numpy as np
import scipy as sp
import matplotlib.pyplot as plt
import random
#constants
N = 10 #dimensions of matrix
J1 = 2.3 #coupling constant
J2 = -21
h = 0 #magnetic field, must be set to 0 to compute observables
counts = 100
T = 2 #temperature
k=1 #boltzmann constant
class initial_lattice:
def __init__(self,N): #create initial matrix of size NxN
self.N=N
self.matrix_lattice()
def matrix_lattice(self):
self.lattice = np.random.choice([-1, 1], (N, N))
self.lattice[::2, ::2] = 0
self.lattice[1::2, 1::2] = 0
lattice1=initial_lattice(N)
#function that sums up all neighbouring sites of the inital position. %N imposes a boundary condition so the function knows when to stop
def diagonal_neighbours(matrix,x,y,N):
d1 = matrix[(x+1)%N, (y+1) %N]
d2 = matrix[(x+1)%N, (y-1) %N]
d3 = matrix[(x-1)%N, (y+1)%N]
d4 = matrix[(x-1) %N, (y-1)%N]
return d1 + d2 + d3 + d4
def lateral_neighbours(matrix,x,y,N):
l1 = matrix[x, (y+2) %N]
l2 = matrix[x, (y-2) %N]
l3 = matrix[(x+2) %N, y]
l4 = matrix[(x-2) %N, y]
return l1 + l2 + l3 + l4
#function for change in energy
def deltaE(matrix, x, y, N, J1, J2, h):
return -(2*J1*matrix[x,y]*(diagonal_neighbours(matrix,x,y,N)))-(2*J2*matrix[x,y]*(lateral_neighbours(matrix,x,y,N)))+2*h*matrix[x,y]
#metropolis algorithim
def metropolis(matrix, counts,N, T, J1,J2, h, k):
for n in range (counts):
for y in range(0, N):
for x in range(0,N):
if deltaE(matrix, x, y, N, J1, J2, h)>=0:
matrix[x,y] *= -1 #if energy change is greater than/equal to 0, flips spin
else:
r = random.random() #generates random number
if r<np.exp(deltaE(matrix, x, y, N, J1, J2, h)/(k*T)):
matrix[x,y] *= -1 #if random number generated between 0 and 1 is less than exp^dE/k*T flips spin
return matrix
print metropolis(lattice1.lattice, counts,N, T, J1, J2, h, k)
plt.imshow(metropolis(lattice1.lattice, counts,N, T, J1, J2, h, k),cmap='bwr',interpolation="none")
plt.show() #plots Ising model in equilibrium
任何帮助将不胜感激。