使用canvas来模拟Ising模型

时间:2018-01-10 13:37:03

标签: python python-2.7 matplotlib

我最初在ComputationalScience上发布过这篇文章,但我认为这可能是最好的,因为我认为我所面临的挑战是使用类和创建数字而不是模拟背后的实际数学/物理。

我正在尝试模拟2D ising模型。模拟由nxn矩阵组成,矩阵的每个元素的值为1或-1,根据代码中概述的条件进行翻转。我想制作一个移动的图形,它基本上为每次迭代产生不同的图像。但我的身影不会出现。我使用一个相同的方法(fig.canvas.draw())到我之前运行的代码没有问题。

这是我的代码:

<div class="col-md-6 col-md-offset-3">
    <div class="input-group input-group-lg">
        <input type="text" class="form-control" placeholder="eg: restaurant templates">
        <input type="submit" value="Search" class="input-group-addon btn btn-primary">
    </div>
</div>

我收到了关于我的数字的警告信息:

  

局部变量图像已分配但从未使用过

1 个答案:

答案 0 :(得分:1)

我已经设法修复了你的代码的所有编程问题,但正如我在评论中所述,我相信你的metropolis部分存在问题,它点头做任何翻转。特别是,我认为你没有正确地进行dH

在我所做的地方放置评论(希望所有这些评论)可以更改内容以运行代码。

import numpy as np
import matplotlib.pyplot as plt

#initialised values 

T = 1.0
N = 5
sweeps = 5

nx = N
ny = N #size of the NxN matrix

#Ising code

class Ising:
    """creating the ising model in this class"""
    #creating a function which creates an initial matrix with randomly orientated spins of 1 and -1    
    def __init__(self, nx, ny, random=False):
        self._lattice = np.random.choice(np.array([-1,1]),size=(N,N))

#creating a function which flips the spin of the individual lattice points        
    def flipspin(self, x, y):
        self._lattice[x,y] *= -1  # simplified the flipping

    def __getitem__(self, key):  # added a special method to be able to do the lattice[(i,j)] lookup
        x, y = key
        return self._lattice[x, y]

    def __str__(self):  # just for debugging purposes
        return str(self._lattice)

    def nearestneighbours(self, N, x, y):  # this was fine, you're doign the sum here already
       return self._lattice[(x - 1) % N, y] + self._lattice[(x + 1) % N, y] + \
           self._lattice[x, (y - 1) % N] + self._lattice[x, (y + 1) % N]

    def show(self):  # using a method to show graphically your 2D matrix
        fig = plt.figure()    
        image = plt.imshow(self._lattice)
        fig.canvas.draw()
        plt.show()    

def Hamiltonianenergy(lattice, x ,y):  # cleaned up to be able to call it without problems
    return 2 * lattice[(x, y)] *  lattice.nearestneighbours(N, x, y)

def metropolis(temperature,eps=1):
    J = 1    
    t = 0
    switch = 0
    energies = 0
    energycount = []
    res = []

    #evaluate inverse temperature
    beta = 1/temperature
    #construct ising lattice
    lattice = Ising(nx,ny,random=True)
    print(lattice)

    #accept or reject according to metropolis function
    for t in range(sweeps):    
        i = np.random.randint(N) #randomly selecting an individual lattice point
        j = np.random.randint(N) 
        dH = Hamiltonianenergy(lattice, i,  j)  # here should be the problem, you have to make the difference of energies before and after the flip!

        if (dH > 0):
            boltzmann = np.exp(-1*beta*dH)
            randNum = np.random.uniform()
            result = True
            if boltzmann <= randNum:
                lattice.flipspin(i, j)  # you where not calling the method properly
                result = False
        else:
            boltzmann = 1
            randNum = 1
            result = True
            energycount.append(energies)

        # some console output
        print(t, i, j, result)
        print("dh: ", dH)
        print(lattice)

        t +=1

        res.append(switch)
        lattice.show()

metropolis(1000)  # running the metropolis function when executing the file