Ising Model 2D Python - 长时间运行和数据波动

时间:2017-10-04 14:45:25

标签: python physics montecarlo

此代码有两个(可能的)问题我可以使用帮助。

我编写了以下代码来计算晶格尺寸为10x10,50x50和100x100的材料的平均能量,磁化强度和比热。

Graphs

显示的图表有很大的波动,我觉得这有两个原因。

  • 首先,我似乎只能在100左右的时间内运行这个程序'放松' 执行实际计算之前的步骤。类似的答案 这里的问题建议做大约1000步,但我的计划 这需要很长时间。
  • 其次,我们的教授给了我们一个暗示 以下内容:

    "如果你以最低的温度开始循环 温度,使用所有旋转的配置作为初始状态 起来。更改温度时,请使用上次旋转配置 作为下一个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()


#----------------------------------------------------------------------

0 个答案:

没有答案