def Accepted(ordered): """ Function which plots the number of accepted configurations in the Metropolis algorithm for two temperatures and for an ordered- and a random initial configuration. Input: ordered: True if ordered, False if random """ titles = ['Random input configuration', 'Ordered input configuration'] fig, ax = plt.subplots(2, 1, figsize=(18, 10), sharex=True) MCsteps = np.linspace(0, MC_cycles, MC_cycles, endpoint=True) for i in range(2): # Initializing the confiuration of the input spin matrix: if ordered == False: spin_matrix = np.random.choice((-1, 1), (num_spins, num_spins)) else: spin_matrix = np.ones((num_spins, num_spins), np.int8) t1 = time.time() exp_values_T1 = ising.MC(spin_matrix, MC_cycles, Temp[0]) t2 = time.time() print("Montecarlo time used:", t2 - t1) t1 = time.time() exp_values_T24 = ising.MC(spin_matrix, MC_cycles, Temp[1]) t2 = time.time() print("Montecarlo time used:", t2 - t1) # Extracting the number of accepted configs: accepted_list_T1 = exp_values_T1[:, 5] accepted_list_T24 = exp_values_T24[:, 5] # Changing to ordered input configuration: ordered = True # Plot: ax[i].set_title('{}'.format(titles[i])) ax[i].plot(MCsteps, accepted_list_T1, color='C2', label='T = 1.0') ax[i].plot(MCsteps, accepted_list_T24, color='C4', label='T = 2.4') ax[i].legend(loc='best') ax[i].set_yscale('log') ax[i].set_xscale('log') ax[1].set_xlabel("Monte Carlo cycles", fontsize=20) fig.text(0.04, 0.5, 'Number of accepted configurations', va='center', rotation='vertical') plt.show()
def plot_MC_cycles(Temp): """ This function creates two plots, each containing subplots of the mean energy and absolute magnetization as functions of Monte Carlo cycles, for random and ordered initial lattice configurations. The two plots show the results of two different input temperatures. """ steps = np.linspace(1, MC_cycles, MC_cycles, endpoint=True) for i, T in enumerate(Temp): # Random initial confiuration spin_matrix_R = np.random.choice((-1, 1), (num_spins, num_spins)) exp_values_R = I.MC(spin_matrix_R, MC_cycles, T) energy_avg_R = np.cumsum(exp_values_R[:, 0]) / np.arange( 1, MC_cycles + 1) magnet_abs_avg_R = np.cumsum(exp_values_R[:, 4]) / np.arange( 1, MC_cycles + 1) Energy_R = energy_avg_R / num_spins**2 MagnetizationAbs_R = magnet_abs_avg_R / num_spins**2 # Ordered initial confiuration spin_matrix_O = np.ones((num_spins, num_spins), np.int8) exp_values_O = I.MC(spin_matrix_O, MC_cycles, T) energy_avg_O = np.cumsum(exp_values_O[:, 0]) / np.arange( 1, MC_cycles + 1) magnet_abs_avg_O = np.cumsum(exp_values_O[:, 4]) / np.arange( 1, MC_cycles + 1) Energy_O = energy_avg_O / (num_spins**2) MagnetizationAbs_O = magnet_abs_avg_O / (num_spins**2) #print('Run time: {}'.format(t1-t0)) fig, ax = plt.subplots(2, 1, figsize=(18, 10), sharex=True) # plot the calculated values plt.suptitle('{}'.format(titles[i])) ax[0].plot(steps, Energy_O, color='C0', label='Ordered') ax[0].plot(steps, Energy_R, color='C1', label='Random') ax[0].set_ylabel("Energy", fontsize=20) ax[0].legend(loc='best') ax[1].plot(steps, MagnetizationAbs_O, color='C0', label='Ordered') ax[1].plot(steps, MagnetizationAbs_R, color='C1', label='Random') ax[1].set_ylabel("Magnetization ", fontsize=20) ax[1].set_xlabel("Monte Carlo cycles", fontsize=20) ax[1].legend(loc='best') #ax[0].title(titles[i]) #plt.savefig('MCT24C2-5.png') plt.show()
def numerical_solution(spin_matrix, n_cycles, temp, L): """ This function calculates the numerical solution of the 2x2 Ising model lattice, using the MC function from ising_model.py """ # Compute quantities quantities = ising.MC(spin_matrix, n_cycles, temp) norm = 1.0/float(n_cycles) E_avg = np.sum(quantities[:,0])*norm M_avg = np.sum(quantities[:,1])*norm E2_avg = np.sum(quantities[:,2])*norm M2_avg = np.sum(quantities[:,3])*norm M_abs_avg = np.sum(quantities[:,4])*norm E_var = (E2_avg - E_avg**2)/(L**2) M_var = (M2_avg - M_avg**2)/(L**2) Energy = E_avg /(L**2) Magnetization = M_avg /(L**2) MagnetizationAbs = M_abs_avg/(L**2) SpecificHeat = E_var /(temp**2) # * L**2? Susceptibility = M_var /(temp) # * L**2? return Energy, Magnetization, MagnetizationAbs, SpecificHeat, Susceptibility
def plotProbability(ordered): """ This function show the probability distribution of energy as histograms for two different temperatures and number of Monte Carlo cycles. The calculations are done by the MC function found in the ising_model script. The mean energy and magnetization is evaluated from a point where steady state is reached. """ for cycles, T in zip(MC_cycles, Temp): # Initializing the confiuration of the input spin matrix if ordered == False: #Random configuration spin_matrix = np.random.choice((-1, 1), (num_spins, num_spins)) else: #Ground state spin_matrix = np.ones((num_spins, num_spins), np.int8) t0 = time.time() exp_values = ising.MC(spin_matrix, cycles, T) t1 = time.time() #If temperature is 1.0 if T == 1.0: sp = 30 norm = 1 / float(cycles - 20000) energy_avg = np.sum(exp_values[19999:, 0]) * norm #print("1:",energy_avg**2) energy2_avg = np.sum(exp_values[19999:, 2]) * norm #E^2 #print("2:",energy2_avg) energy_var = (energy2_avg - energy_avg**2) / (num_spins**2) E = exp_values[19999:, 0] E = E / (num_spins**2) if T == 2.4: sp = 160 norm = 1 / float(cycles - 40000) energy_avg = np.sum(exp_values[39999:, 0]) * norm #print("1:",energy_avg**2) energy2_avg = np.sum(exp_values[39999:, 2]) * norm #print("2:",energy2_avg) energy_var = (energy2_avg - energy_avg**2) / (num_spins**2) E = exp_values[19999:, 0] E = E / (num_spins**2) print("Variance T=%s:" % str(T), energy_var) n, bins, patches = plt.hist(E, sp, facecolor='plum') plt.xlabel('$E$') plt.ylabel('Energy distribution') plt.title('Energy distribution at $k_BT=%s$' % str(T)) plt.grid(True) plt.show()
def plotProbability(ordered): """ Function which plots the probabilities of finding an energy E. Being done for two temperatures in the list Temp, and for two corresponding numbers of Monte Carlo cycles. Input: ordered: True if ordered, False if random """ for cycles, T in zip(MC_cycles, Temp): # Initializing the confiuration of the input spin matrix: if ordered == False: spin_matrix = np.random.choice((-1, 1), (num_spins, num_spins)) else: spin_matrix = np.ones((num_spins,num_spins), np.int8) t1 = time.time() exp_values = ising.MC(spin_matrix, cycles, T) t2 = time.time() print("Montecarlo time used:", t2-t1) #If the temperature is 1.0: if T == 1.0: spacing = 30 norm = 1/float(cycles-20000) energy_avg = np.sum(exp_values[19999:, 0])*norm energy2_avg = np.sum(exp_values[19999:, 2])*norm energy_var = (energy2_avg - energy_avg**2)/(num_spins**2) E = exp_values[19999:, 0] E = E/(num_spins**2) #If the temperature is 2.4: if T == 2.4: spacing = 160 norm = 1/float(cycles-40000) energy_avg = np.sum(exp_values[39999:, 0])*norm energy2_avg = np.sum(exp_values[39999:, 2])*norm energy_var = (energy2_avg - energy_avg**2)/(num_spins**2) E = exp_values[39999:, 0] E = E/(num_spins**2) print("Variance T=%s:"%str(T), energy_var) n, bins, patches = plt.hist(E, spacing, facecolor='blue') plt.xlabel('$E$') plt.ylabel('Number of times the given energy appears') plt.title('Energy distribution at $k_BT=%s$'%str(T)) plt.grid(True) plt.show()
def Accepted(ordered): """ This function plots the number of accepted configurations in the Ising model as function of Monte Carlo cycles, calculated by the imported function MC from ising_model.py. Two subplots are produced, one for steady initial configuration of the lattice and one for a random configuration, both containing the accepted values for temperature, T=1.0 and T=2.4. """ titles = ['Random input configuration', 'Ordered input configuration'] fig, ax = plt.subplots(2, 1, figsize=(18, 7), sharex=True) Steps = np.linspace(0, MC_cycles, MC_cycles, endpoint=True) for i in range(2): # Initializing the confiuration of the input spin matrix if ordered == False: #random configuration spin_matrix = np.random.choice((-1, 1), (num_spins, num_spins)) else: #ground state spin_matrix = np.ones((num_spins, num_spins), np.int8) # Extracting the relevant values from the output matrix from the ising_model exp_values_T1 = I.MC(spin_matrix, MC_cycles, Temp[0]) exp_values_T24 = I.MC(spin_matrix, MC_cycles, Temp[1]) accepted_list_T1 = exp_values_T1[:, 5] accepted_list_T24 = exp_values_T24[:, 5] ordered = True ax[i].set_title('{}'.format(titles[i])) ax[i].loglog(Steps, accepted_list_T1, color='C2', label='T = 1.0') ax[i].loglog(Steps, accepted_list_T24, color='C4', label='T = 2.4') ax[i].legend(loc='best') ax[1].set_xlabel("Monte Carlo cycles", fontsize=20) fig.text(0.04, 0.5, 'Number of accepted configurations', va='center', rotation='vertical')
def plotProbability(): """ This function show the probability distribution of energy as histograms for two different temperatures and number of Monte Carlo cycles. The calculations are done by the MC function found in the ising_model script. The mean energy and magnetization is evaluated from a point where steady state is reached. """ for cycles, T in zip(MC_cycles, Temp): # Initializing the confiuration of the input spin matrix #Ground state spin_matrix = np.ones((num_spins, num_spins), np.int8) exp_values = I.MC(spin_matrix, cycles, T) #If temperature is 1.0 if T == 1.0: # Bin spacing for histogram sp = 30 # Normalization constant norm = 1.0 / float(cycles - 20000) # Extracting the values of interest energy_avg = np.sum(exp_values[19999:, 0]) * norm energy2_avg = np.sum(exp_values[19999:, 2]) * norm #E^2 energy_var = (energy2_avg - energy_avg**2) / (num_spins**2) E = exp_values[19999:, 0] / (num_spins**2) if T == 2.4: # Bin spacing for histogram sp = 160 # Normalization constant norm = 1 / float(cycles - 40000) # Extracting the values of interest energy_avg = np.sum(exp_values[39999:, 0]) * norm energy2_avg = np.sum(exp_values[39999:, 2]) * norm energy_var = (energy2_avg - energy_avg**2) / (num_spins**2) E = exp_values[39999:, 0] / (num_spins**2) print("Variance T=%s:" % str(T), energy_var) n, bins, patches = plt.hist(E, sp, facecolor='C0') plt.xlabel('$E$') plt.ylabel('Energy distribution P(E)') plt.title('Energy distribution at $k_BT=%s$' % str(T)) plt.grid(True) plt.show()
def numerical_solution(spin_matrix, num_cycles): #This function calculates the numerical solution of our 2x2 ising model #lattice, using the MC function from ising_model.py exp_values = I.MC(spin_matrix, num_cycles, temp) norm = 1.0 / float(num_cycles) energy_avg = np.sum(exp_values[:, 0]) * norm magnet_avg = np.sum(exp_values[:, 1]) * norm energy2_avg = np.sum(exp_values[:, 2]) * norm magnet2_avg = np.sum(exp_values[:, 3]) * norm magnet_abs_avg = np.sum(exp_values[:, 4]) * norm energy_var = (energy2_avg - energy_avg**2) / (num_spins**2) magnet_var = (magnet2_avg - magnet_avg**2) / (num_spins**2) Energy = energy_avg / (num_spins**2) Magnetization = magnet_avg / (num_spins**2) MagnetizationAbs = magnet_abs_avg / (num_spins**2) SpecificHeat = energy_var / (temp**2) Susceptibility = magnet_var / (temp) return Energy, Magnetization, MagnetizationAbs, SpecificHeat, Susceptibility
def numerical_solution(spin_matrix, num_cycles): exp_values = ising.MC(spin_matrix, num_cycles, temp) norm = 1.0 / float(num_cycles) # <E>, <M>, <E^2>, <M^2> and <|M|>: energy_avg = np.sum(exp_values[:, 0]) * norm magnet_avg = np.sum(exp_values[:, 1]) * norm energy2_avg = np.sum(exp_values[:, 2]) * norm magnet2_avg = np.sum(exp_values[:, 3]) * norm magnet_abs_avg = np.sum(exp_values[:, 4]) * norm # Variances per spin: energy_var = (energy2_avg - energy_avg**2) / (num_spins**2) magnet_var = (magnet2_avg - magnet_avg**2) / (num_spins**2) # Expectation values and quantities per spin: Energy = energy_avg / (num_spins**2) Magnetization = magnet_avg / (num_spins**2) MagnetizationAbs = magnet_abs_avg / (num_spins**2) SpecificHeat = energy_var / (temp**2) Susceptibility = magnet_var / (temp) return Energy, Magnetization, MagnetizationAbs, SpecificHeat, Susceptibility
# Number of Monte Carlo cycles for the calculation MC_cycles = 1000000 norm = 1.0 / float(MC_cycles - 40000) # Initializing output matrices E = np.zeros((len(L), len(T))) M_abs = np.zeros((len(L), len(T))) m_av = np.zeros((len(L), len(T))) C_v = np.zeros((len(L), len(T))) X = np.zeros((len(L), len(T))) # Looping over all lattice sizes and all temperature steps for i, spins in enumerate(L): spin_matrix = np.ones((L[i], L[i]), np.int8) for j, temp in enumerate(T): exp_values = I.MC(spin_matrix, MC_cycles, temp) # Extracting variables of interest from the output matrix energy_avg = np.sum(exp_values[40000:, 0]) * norm magnet_abs_avg = np.sum(exp_values[40000:, 4]) * norm energy2_avg = np.sum(exp_values[40000:, 2]) * norm magnet2_avg = np.sum(exp_values[40000:, 3]) * norm energy_var = (energy2_avg - energy_avg**2) / ((spins)**2) magnet_var = (magnet2_avg - magnet_abs_avg**2) / ((spins)**2) E[i, j] = (energy_avg) / (spins**2) M_abs[i, j] = (magnet_abs_avg) / (spins**2) C_v[i, j] = energy_var / temp**2 X[i, j] = magnet_var / temp # Print to keep track of calculation print(temp) print(spins)
# Number of Monte Carlo cycles for the calculation: MC_cycles = 200000 norm = 1.0 / float(MC_cycles - 40000) # Initializing output matrices: E = np.zeros((len(L), len(T))) M_abs = np.zeros((len(L), len(T))) m_av = np.zeros((len(L), len(T))) C_v = np.zeros((len(L), len(T))) X = np.zeros((len(L), len(T))) # Looping over all lattice sizes and all temperature steps: for i, spins in enumerate(L): spin_matrix = np.ones((L[i], L[i]), np.int8) for j, temp in enumerate(T): exp_values = ising.MC(spin_matrix, MC_cycles, temp) energy_avg = np.sum(exp_values[40000:, 0]) * norm magnet_abs_avg = np.sum(exp_values[40000:, 4]) * norm energy2_avg = np.sum(exp_values[40000:, 2]) * norm magnet2_avg = np.sum(exp_values[40000:, 3]) * norm energy_var = (energy2_avg - energy_avg**2) / ((spins)**2) magnet_var = (magnet2_avg - magnet_abs_avg**2) / ((spins)**2) E[i, j] = (energy_avg) / (spins**2) M_abs[i, j] = (magnet_abs_avg) / (spins**2) C_v[i, j] = energy_var / temp**2 X[i, j] = magnet_var / temp print(temp) print(spins)
def plot_MC_cycles(Temp): """ Plots the mean energy and the mean magnetization as functions of Monte Carlo cycles. This is being done for the two temperatures. Input: Temp: The temperatures (Two values in a list) """ MCsteps = np.linspace(1, MC_cycles, MC_cycles, endpoint=True) for i, T in enumerate(Temp): # Random spin configuration: spin_matrix_R = np.random.choice((-1, 1), (num_spins, num_spins)) time1 = time.time() exp_values_R = ising.MC(spin_matrix_R, MC_cycles, T) time2 = time.time() print("Montecarlo time used:", time2 - time1) # Mean values: energy_avg_R = np.cumsum(exp_values_R[:, 0]) / np.arange( 1, MC_cycles + 1) magnet_abs_avg_R = np.cumsum(exp_values_R[:, 4]) / np.arange( 1, MC_cycles + 1) # Mean values per spin: Energy_R = energy_avg_R / num_spins**2 MagnetizationAbs_R = magnet_abs_avg_R / num_spins**2 # Ordered spin confiuration: spin_matrix_O = np.ones((num_spins, num_spins), np.int8) time1 = time.time() exp_values_O = ising.MC(spin_matrix_O, MC_cycles, T) time2 = time.time() print("Montecarlo time used:", time2 - time1) # Mean values: energy_avg_O = np.cumsum(exp_values_O[:, 0]) / np.arange( 1, MC_cycles + 1) magnet_abs_avg_O = np.cumsum(exp_values_O[:, 4]) / np.arange( 1, MC_cycles + 1) # Mean values per spin: Energy_O = energy_avg_O / (num_spins**2) MagnetizationAbs_O = magnet_abs_avg_O / (num_spins**2) # Plot: fig, ax = plt.subplots(2, 1, figsize=(18, 10), sharex=True) # plot the calculated values plt.suptitle('{}'.format( 'Energy and magnetization vs. number of Monte Carlo cycles. T=%s' % str(T))) ax[0].plot(MCsteps, Energy_O, color='C0', label='Ordered') ax[0].plot(MCsteps, Energy_R, color='C1', label='Random') ax[0].set_ylabel("Mean energy", fontsize=15) ax[0].legend(loc='best') ax[1].plot(MCsteps, MagnetizationAbs_O, color='C0', label='Ordered') ax[1].plot(MCsteps, MagnetizationAbs_R, color='C1', label='Random') ax[1].set_ylabel("Mean magnetization (abs. value)", fontsize=15) ax[1].set_xlabel("Monte Carlo cycles", fontsize=15) ax[1].legend(loc='best') plt.show()