此代码有两个(可能的)问题我可以使用帮助。
我编写了以下代码来计算晶格尺寸为10x10,50x50和100x100的材料的平均能量,磁化强度和比热。
显示的图表有很大的波动,我觉得这有两个原因。
其次,我们的教授给了我们一个暗示 以下内容:
"如果你以最低的温度开始循环 温度,使用所有旋转的配置作为初始状态 起来。更改温度时,请使用上次旋转配置 作为下一个Nwait MMC步骤的第一个配置。 - 这将 减少数据的波动"
我一直试图通过举例来实现这一点,
if m == 1:
s = np.ones(10,10)
else:
config = initialstate(N)
<=>在for循环中,N = 10x10。
但这只能部分地解决它,因为我没有使用最后一次旋转配置作为下一个放松步骤的第一个配置。
代码:
import numpy as np
from numpy.random import rand
import matplotlib.pyplot as plt
#----------------------------------------------------------------------
## BLOCK OF FUNCTIONS USED IN THE MAIN CODE
#----------------------------------------------------------------------
def initialstate(N):
''' generates a random spin configuration for initial condition'''
state = 2*np.random.randint(2, size=(N,N),dtype='int64')-1
return state
def mcmove(config, beta):
'''Monte Carlo move using Metropolis algorithm '''
for i in range(N):
for j in range(N):
a = np.random.randint(0, N,dtype='int64')
b = np.random.randint(0, N,dtype='int64')
s = config[a, b]
nb = config[(a+1)%N,b] + config[a,(b+1)%N] + config[(a-1)%N,b] + config[a,(b-1)%N]
energy = 2*s*nb
if energy < 0:
s *= -1
elif rand() < np.exp(-energy*beta):
s *= -1
config[a, b] = s
return config
def calcEnergy(config):
'''Energy of a given configuration'''
energy = 0
for i in range(len(config)):
for j in range(len(config)):
S = config[i,j]
nb = config[(i+1)%N, j] + config[i,(j+1)%N] + config[(i-1)%N, j] + config[i,(j-1)%N]
energy += -nb*S
return energy/4.
def calcMag(config):
'''Magnetization of a given configuration'''
mag = np.sum(config)
return mag
#----------------------------------------------------------------------
## MAIN PART OF THE CODE
#----------------------------------------------------------------------
nt = 20 # number of temperature points
eqSteps = 100 # number of MC sweeps for equilibration
mcSteps = 100 # number of MC sweeps for calculation
T = np.linspace(1, 4, nt) #temperature
Energy_10 = np.zeros(nt,dtype='int64')
Magnetization_10 = np.zeros(nt,dtype='int64')
SpecificHeat_10 = np.zeros(nt,dtype='int64')
Energy_20 = np.zeros(nt,dtype='int64')
Magnetization_20 = np.zeros(nt,dtype='int64')
SpecificHeat_20 = np.zeros(nt,dtype='int64')
Energy_30 = np.zeros(nt,dtype='int64')
Magnetization_30 = np.zeros(nt,dtype='int64')
SpecificHeat_30 = np.zeros(nt,dtype='int64')
for m in range(len(T)): #for loop for 10x10 lattice
E1 = M1 = 0
N = 10 # size of the lattice, N x N
config = initialstate(N)
for i in range(eqSteps):
mcmove(config, 1.0/T[m])
for i in range(mcSteps):
mcmove(config, 1.0/T[m]) # monte carlo moves
Ene = calcEnergy(config) # calculate the energy
Mag = calcMag(config) # calculate the magnetisation
E1 = E1 + Ene
M1 = M1 + Mag
Energy_10[m] = E1/(N**2)
Magnetization_10[m] = M1/(N**2)
SpecificHeat_10[m] = (((T[m]**2)*(E1/(N**2))*(E1)-(E1/(N**2))**2))/(N**2)
for m in range(len(T)): #for loop for 50x50 lattice
E1 = M1 = 0
N = 50
config = initialstate(N)
for i in range(eqSteps):
mcmove(config, 1.0/T[m])
for i in range(mcSteps):
mcmove(config, 1.0/T[m]) # monte carlo moves
Ene = calcEnergy(config) # calculate the energy
Mag = calcMag(config) # calculate the magnetisation
E1 = E1 + Ene
M1 = M1 + Mag
Energy_20[m] = E1/(N**2)
Magnetization_20[m] = M1/(N**2)
SpecificHeat_20[m] = ((T[m]**2)*(E1/(N**2))*(E1)-(E1/(N**2))**2)/(N**2)
for m in range(len(T)): #for loop for 100x100 lattice
E1 = M1 = 0
N = 100
config = initialstate(N)
for i in range(eqSteps):
mcmove(config, 1.0/T[m])
for i in range(mcSteps):
mcmove(config, 1.0/T[m]) # monte carlo moves
Ene = calcEnergy(config) # calculate the energy
Mag = calcMag(config) # calculate the magnetisation
E1 = E1 + Ene
M1 = M1 + Mag
Energy_30[m] = E1/(N**2)
Magnetization_30[m] = M1/(N**2)
SpecificHeat_30[m] = ((T[m]**2)*(E1/(N**2))*(E1)-(E1/(N**2))**2)/(N**2)
#----------------------------------------------------------------------
# Plot the Energy, Magnetization and Specific Heat
#----------------------------------------------------------------------
f = plt.figure(figsize=(18, 10), dpi=80, facecolor='w', edgecolor='k');
sp = f.add_subplot(2, 2, 1 );
plt.plot(T, Energy_10, 'g',label = 'N=10')
plt.plot(T, Energy_20, 'r',label = 'N=50')
plt.plot(T, Energy_30, 'b',label = 'N=100')
plt.legend()
plt.xlabel("Temperature (T)", fontsize=20);
plt.ylabel("Energy ", fontsize=20);
plt.show()
sp = f.add_subplot(2, 2, 2 );
plt.plot(T, abs(Magnetization_10), 'g',label = 'N=10')
plt.plot(T, abs(Magnetization_20), 'r',label = 'N=50')
plt.plot(T, abs(Magnetization_30), 'b',label = 'N=100')
plt.legend()
plt.xlabel("Temperature (T)", fontsize=20);
plt.ylabel("Magnetization ", fontsize=20);
plt.show()
sp = f.add_subplot(2, 2, 3 );
plt.plot(T, SpecificHeat_10, 'g',label = 'N=10')
plt.plot(T, SpecificHeat_20, 'r',label = 'N=50')
plt.plot(T, SpecificHeat_30, 'b',label = 'N=100')
plt.legend()
plt.xlabel("Temperature (T)", fontsize=20);
plt.ylabel("Specific Heat ", fontsize=20);
plt.show()
#----------------------------------------------------------------------