class Simulation: # Seed random number generator: self.rng() will give a random float from the interval [0,1) rng = alpstools.rng(42) def __init__(self, beta, L): self.L = L self.beta = beta # Init exponential map self.exp_table = dict() for E in range(-4, 5, 2): self.exp_table[E] = math.exp(2 * beta * E) # Init random spin configuration self.spins = [[2 * self.randint(2) - 1 for j in range(L)] for i in range(L)] # Init observables self.energy = alpsalea.RealObservable('E') self.magnetization = alpsalea.RealObservable('m') self.abs_magnetization = alpsalea.RealObservable('|m|') def save(self, filename): pyalps.save_parameters( filename, { 'L': self.L, 'BETA': self.beta, 'SWEEPS': self.n, 'THERMALIZATION': self.ntherm }) self.abs_magnetization.save(filename) self.energy.save(filename) self.magnetization.save(filename) def run(self, ntherm, n): # Thermalize for ntherm steps self.n = n self.ntherm = ntherm while ntherm > 0: self.step() ntherm = ntherm - 1 # Run n steps while n > 0: self.step() self.measure() n = n - 1 # Print observables print '|m|:\t', self.abs_magnetization.mean, '+-', self.abs_magnetization.error, ',\t tau =', self.abs_magnetization.tau print 'E:\t', self.energy.mean, '+-', self.energy.error, ',\t tau =', self.energy.tau print 'm:\t', self.magnetization.mean, '+-', self.magnetization.error, ',\t tau =', self.magnetization.tau def step(self): for s in range(self.L * self.L): # Pick random site k=(i,j) ... # Measure local energy e = -s_k * sum_{l nn k} s_l ... # Flip s_k with probability exp(2 beta e) ... def measure(self): E = 0. # energy M = 0. # magnetization for i in range(self.L): for j in range(self.L): E -=... M +=... # Add sample to observables self.energy << E / (self.L * self.L) self.magnetization << M / (self.L * self.L) self.abs_magnetization << abs(M) / (self.L * self.L) # Random int from the interval [0,max) def randint(self, max): return int(max * self.rng())
class Simulation: # Seed random number generator: self.rng() will give a random float from the interval [0,1) rng = alpstools.rng(42) def __init__(self,beta,L): self.L = L self.beta = beta # Init exponential map self.exp_table = dict() for E in range(-8,10,4): self.exp_table[E] = math.exp(2*beta*E) #self.exp_table[E] = math.exp(-beta*E) #math.exp(beta*E) # Init random spin configuration self.spins = [ [2*self.randint(2)-1 for j in range(L)] for i in range(L) ] # Init observables self.energy = alpsalea.RealObservable('E') self.magnetization = alpsalea.RealObservable('m') self.abs_magnetization = alpsalea.RealObservable('|m|') self.magnetization_2 = alpsalea.RealObservable('m^2') self.magnetization_4 = alpsalea.RealObservable('m^4') self.accepted = 0 def save(self, filename): pyalps.save_parameters(filename, {'L':self.L, 'BETA':self.beta, 'SWEEPS':self.n, 'THERMALIZATION':self.ntherm}) self.abs_magnetization.save(filename) self.energy.save(filename) self.magnetization.save(filename) self.magnetization_2.save(filename) self.magnetization_4.save(filename) def run(self,ntherm,n): # Thermalize for ntherm steps self.n = n self.ntherm = ntherm while ntherm > 0: self.step() ntherm = ntherm-1 # Run n steps while n > 0: self.step() self.measure() n = n-1 # Print observables print '|m|:\t', self.abs_magnetization.mean, '+-', self.abs_magnetization.error, ',\t tau =', self.abs_magnetization.tau print 'E:\t', self.energy.mean, '+-', self.energy.error, ',\t tau =', self.energy.tau print 'm:\t', self.magnetization.mean, '+-', self.magnetization.error, ',\t tau =', self.magnetization.tau def energyLocal(self, spin, i, j): e = self.spins[(i-1+self.L)%self.L][j] + self.spins[(i+1)%self.L][j] + self.spins[i][(j-1+self.L)%self.L] + self.spins[i][(j+1)%self.L] e *= -spin return e def step(self): for s in range(self.L*self.L): # Pick random site k=(i,j) i = self.randint(self.L) j = self.randint(self.L) newSpin = -self.spins[i][j] de = self.energyLocal(newSpin, i, j) - self.energyLocal(self.spins[i][j], i, j) #de = self.deltaEnergy(i, j) # Flip s_k with probability exp(2 beta e) #if e > 0 or self.rng() < self.exp_table[e]: # self.spins[i][j] = -self.spins[i][j] if de < 0 or self.rng() < math.exp(-self.beta*de): #de<=0 breaks the binder plot ... self.spins[i][j] = newSpin self.accepted += 1 def measure(self): E = 0. # energy M = 0. # magnetization for i in range(self.L): for j in range(self.L): E -= self.spins[i][j] * (self.spins[(i+1)%self.L][j] + self.spins[i][(j+1)%self.L]) M += self.spins[i][j] # Add sample to observables self.energy << E/(self.L*self.L) self.magnetization << M/(self.L*self.L) self.abs_magnetization << abs(M)/(self.L*self.L) self.magnetization_2 << (M/(self.L*self.L))*(M/(self.L*self.L)) self.magnetization_4 << (M/(self.L*self.L))*(M/(self.L*self.L))*(M/(self.L*self.L))*(M/(self.L*self.L)) # Random int from the interval [0,max) def randint(self,max): return int(max*self.rng())
class Simulation: # Seed random number generator: self.rng() will give a random float from the interval [0,1) rng = alpstools.rng(42) def __init__(self, beta, L, model=None): # Init size and temp self.L = L self.beta = beta # Init random spin configuration self.spins = [[ spin.Spin(sx=0.0, sy=0.0, sz=2 * self.randint(2) - 1) for j in range(L) ] for i in range(L)] # Init observables self.energy = alpsalea.RealObservable('E') self.magnetization = alpsalea.RealObservable('m') self.abs_magnetization = alpsalea.RealObservable('|m|') self.magnetization_2 = alpsalea.RealObservable('m^2') self.magnetization_4 = alpsalea.RealObservable('m^4') self.accepted = 0 #============================================================================== # HAMILTONIANS #============================================================================== def isingH(spin, i, j): e = self.spins[(i-1+self.L)%self.L][j].sz +\ self.spins[(i+1)%self.L][j].sz +\ self.spins[i][(j-1+self.L)%self.L].sz +\ self.spins[i][(j+1)%self.L].sz e *= -spin.sz return e def antiIsingH(spin, i, j): e = self.spins[(i-1+self.L)%self.L][j].sz +\ self.spins[(i+1)%self.L][j].sz +\ self.spins[i][(j-1+self.L)%self.L].sz +\ self.spins[i][(j+1)%self.L].sz e *= spin.sz return e # currently not long-range. def dipoledipoleH(spin, i, j): rCutOff = 3 e = 0 for dx in range(-1, 2, 2): for dy in range(-1, 2, 2): if (dx * dx + dy * dy > rCutOff * rCutOff): #hard code for now. r = math.sqrt(dx * dx + dy * dy) rvec = spin.Spin(sx=dx, sy=dy, sz=0.0) e += self.spins[i][j].dot( self.spins[(i + dx) % self.L][(j + dy) % self.L]) e += (self.spins[i][j].dot(rvec)) * (self.spins[ (i + dx) % self.L][(j + dy) % self.L].dot(rvec)) e *= 1.0 / (r * r * r) return e #============================================================================== # SPIN MOVE / FLIP TYPES #============================================================================== def flip180(spinToFlip): return spin.Spin(sx=spinToFlip.sx, sy=spinToFlip.sy, sz=-spinToFlip.sz) self.Potts6LookUp = [[0, 0, 1], [0, 0, -1], [0, 1, 0], [0, -1, 0], [1, 0, 0], [-1, 0, 0]] def flipPotts6(spinToFlip): whichVector = self.randint(len(self.Potts6LookUp)) sx = self.Potts6LookUp[whichVector][0] sy = self.Potts6LookUp[whichVector][1] sz = self.Potts6LookUp[whichVector][2] return spin.Spin(sx=sx, sy=sy, sz=sz) if model == 'Ising': self.energyLocal = isingH self.flip = flip180 elif model == 'AntiFerroIsing': self.energyLocal = antiIsingH self.flip = flip180 elif model == 'dipole-dipole6': self.energyLocal = dipoledipoleH self.flip = flipPotts6 def save(self, filename): pyalps.save_parameters( filename, { 'L': self.L, 'BETA': self.beta, 'SWEEPS': self.n, 'THERMALIZATION': self.ntherm }) self.abs_magnetization.save(filename) self.energy.save(filename) self.magnetization.save(filename) self.magnetization_2.save(filename) self.magnetization_4.save(filename) def run(self, ntherm, n): # Thermalize for ntherm steps self.n = n self.ntherm = ntherm while ntherm > 0: self.step() ntherm = ntherm - 1 # Run n steps while n > 0: self.step() self.measure() n = n - 1 # Print observables print '|m|:\t', self.abs_magnetization.mean, '+-', self.abs_magnetization.error, ',\t tau =', self.abs_magnetization.tau print 'E:\t', self.energy.mean, '+-', self.energy.error, ',\t tau =', self.energy.tau print 'm:\t', self.magnetization.mean, '+-', self.magnetization.error, ',\t tau =', self.magnetization.tau def step(self): for s in range(self.L * self.L): # Pick random site k=(i,j) i = self.randint(self.L) j = self.randint(self.L) newSpin = self.flip(self.spins[i][j]) de = self.energyLocal(newSpin, i, j) - self.energyLocal( self.spins[i][j], i, j) #de = self.deltaEnergy(i, j) # Flip s_k with probability exp(2 beta e) #if e > 0 or self.rng() < self.exp_table[e]: # self.spins[i][j] = -self.spins[i][j] if de < 0 or self.rng() < math.exp( -self.beta * de): #de<=0 breaks the binder plot ... self.spins[i][j] = newSpin self.accepted += 1 def measure(self): E = 0. # energy M = 0. # magnetization for i in range(self.L): for j in range(self.L): E -= self.spins[i][j].sz * (self.spins[ (i + 1) % self.L][j].sz + self.spins[i][(j + 1) % self.L].sz) M += self.spins[i][j].sz # Add sample to observables self.energy << E / (self.L * self.L) self.magnetization << M / (self.L * self.L) self.abs_magnetization << abs(M) / (self.L * self.L) self.magnetization_2 << (M / (self.L * self.L)) * (M / (self.L * self.L)) self.magnetization_4 << (M / (self.L * self.L)) * ( M / (self.L * self.L)) * (M / (self.L * self.L)) * (M / (self.L * self.L)) def spinsToFile(self, outputFile): if outputFile is None: raise TypeError("Please supply an output file name!") else: f = open(outputFile, 'w') for i in range(self.L): for j in range(self.L): f.write(str(i)+','+str(j)+','+\ str(self.spins[i][j].sx)+','+\ str(self.spins[i][j].sy)+','+\ str(self.spins[i][j].sz)+'\n') f.close() print 'saved spins to ' + str(outputFile) # Random int from the interval [0,max) def randint(self, max): return int(max * self.rng())