This commit is contained in:
guanjihuan 2022-01-22 16:28:25 +08:00
parent 29f76af7fa
commit 03955990aa
9 changed files with 418 additions and 407 deletions

View File

@ -1,33 +1,33 @@
""" """
This code is supported by the website: https://www.guanjihuan.com This code is supported by the website: https://www.guanjihuan.com
The newest version of this code is on the web page: https://www.guanjihuan.com/archives/1247 The newest version of this code is on the web page: https://www.guanjihuan.com/archives/1247
""" """
import random import random
import math import math
import numpy as np import numpy as np
from scipy.stats import norm from scipy.stats import norm
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
def function(x): # 期望样品的分布target distribution function def function(x): # 期望样品的分布target distribution function
y = (norm.pdf(x, loc=2, scale=1)+norm.pdf(x, loc=-5, scale=1.5))/2 # loc代表了均值,scale代表标准差 y = (norm.pdf(x, loc=2, scale=1)+norm.pdf(x, loc=-5, scale=1.5))/2 # loc代表了均值,scale代表标准差
return y return y
T = 100000 # 取T个样品 T = 100000 # 取T个样品
pi = [0 for i in range(T)] # 任意选定一个马尔科夫链初始状态 pi = [0 for i in range(T)] # 任意选定一个马尔科夫链初始状态
for t in np.arange(1, T): for t in np.arange(1, T):
pi_star = np.random.uniform(-10, 10) # a proposed distribution 例如是均匀分布的或者是一个依赖pi[t - 1]的分布 pi_star = np.random.uniform(-10, 10) # a proposed distribution 例如是均匀分布的或者是一个依赖pi[t - 1]的分布
alpha = min(1, (function(pi_star) / function(pi[t - 1]))) # 接收率 alpha = min(1, (function(pi_star) / function(pi[t - 1]))) # 接收率
u = random.uniform(0, 1) u = random.uniform(0, 1)
if u < alpha: if u < alpha:
pi[t] = pi_star # 以alpha的概率接收转移 pi[t] = pi_star # 以alpha的概率接收转移
else: else:
pi[t] = pi[t - 1] # 不接收转移 pi[t] = pi[t - 1] # 不接收转移
pi = np.array(pi) # 转成numpy格式 pi = np.array(pi) # 转成numpy格式
print(pi.shape) # 查看抽样样品的维度 print(pi.shape) # 查看抽样样品的维度
plt.plot(pi, function(pi), '*') # 画出抽样样品期望的分布 # 或用plt.scatter(pi, function(pi)) plt.plot(pi, function(pi), '*') # 画出抽样样品期望的分布 # 或用plt.scatter(pi, function(pi))
plt.hist(pi, bins=100, density=1, facecolor='red', alpha=0.7) # 画出抽样样品的分布 # bins是分布柱子的个数density是归一化后面两个参数是管颜色的 plt.hist(pi, bins=100, density=1, facecolor='red', alpha=0.7) # 画出抽样样品的分布 # bins是分布柱子的个数density是归一化后面两个参数是管颜色的
plt.show() plt.show()

View File

@ -1,18 +1,18 @@
% This code is supported by the website: https://www.guanjihuan.com % This code is supported by the website: https://www.guanjihuan.com
% The newest version of this code is on the web page: https://www.guanjihuan.com/archives/1247 % The newest version of this code is on the web page: https://www.guanjihuan.com/archives/1247
clc;clear all;clf; clc;clear all;clf;
s=100000; % s=100000; %
f=[1,2,3,3,3,3,6,5,4,3,2,1]; % f=[1,2,3,3,3,3,6,5,4,3,2,1]; %
d=zeros(1,s); % d=zeros(1,s); %
x=1; x=1;
for i=1:s for i=1:s
y=unidrnd(12); % 112 y=unidrnd(12); % 112
alpha=min(1,f(y)/f(x)); % alpha=min(1,f(y)/f(x)); %
u=rand; u=rand;
if u<alpha % alpha if u<alpha % alpha
x=y; x=y;
end end
d(i)=x; d(i)=x;
end end
hist(d,1:1:12); hist(d,1:1:12);

View File

@ -1,97 +1,97 @@
""" """
This code is supported by the website: https://www.guanjihuan.com This code is supported by the website: https://www.guanjihuan.com
The newest version of this code is on the web page: https://www.guanjihuan.com/archives/1249 The newest version of this code is on the web page: https://www.guanjihuan.com/archives/1249
""" """
import random import random
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import numpy as np import numpy as np
import copy import copy
import math import math
import time import time
def main(): def main():
size = 30 # 体系大小 size = 30 # 体系大小
T = 2 # 温度 T = 2 # 温度
ising = get_one_sample(sizeOfSample=size, temperature=T) # 得到符合玻尔兹曼分布的ising模型 ising = get_one_sample(sizeOfSample=size, temperature=T) # 得到符合玻尔兹曼分布的ising模型
plot(ising) # 画图 plot(ising) # 画图
energy_s = [] energy_s = []
for i in range(size): for i in range(size):
for j in range(size): for j in range(size):
energy_s0 = getEnergy(i=i, j=j, S=ising) # 获取格点的能量 energy_s0 = getEnergy(i=i, j=j, S=ising) # 获取格点的能量
energy_s = np.append(energy_s, [energy_s0], axis=0) energy_s = np.append(energy_s, [energy_s0], axis=0)
plt.hist(energy_s, bins=50, density=1, facecolor='red', alpha=0.7) # 画出格点能量分布 # bins是分布柱子的个数density是归一化后面两个参数是管颜色的 plt.hist(energy_s, bins=50, density=1, facecolor='red', alpha=0.7) # 画出格点能量分布 # bins是分布柱子的个数density是归一化后面两个参数是管颜色的
plt.show() plt.show()
def get_one_sample(sizeOfSample, temperature): def get_one_sample(sizeOfSample, temperature):
S = 2 * np.pi * np.random.random(size=(sizeOfSample, sizeOfSample)) # 随机初始状态角度是0到2pi S = 2 * np.pi * np.random.random(size=(sizeOfSample, sizeOfSample)) # 随机初始状态角度是0到2pi
print('体系大小:', S.shape) print('体系大小:', S.shape)
initialEnergy = calculateAllEnergy(S) # 计算随机初始状态的能量 initialEnergy = calculateAllEnergy(S) # 计算随机初始状态的能量
print('系统的初始能量是:', initialEnergy) print('系统的初始能量是:', initialEnergy)
newS = np.array(copy.deepcopy(S)) newS = np.array(copy.deepcopy(S))
for i00 in range(1000): # 循环一定次数,得到平衡的抽样分布 for i00 in range(1000): # 循环一定次数,得到平衡的抽样分布
newS = Metropolis(newS, temperature) # Metropolis方法抽样得到玻尔兹曼分布的样品体系 newS = Metropolis(newS, temperature) # Metropolis方法抽样得到玻尔兹曼分布的样品体系
newEnergy = calculateAllEnergy(newS) newEnergy = calculateAllEnergy(newS)
if np.mod(i00, 100) == 0: if np.mod(i00, 100) == 0:
print('循环次数%i, 当前系统能量是:' % (i00+1), newEnergy) print('循环次数%i, 当前系统能量是:' % (i00+1), newEnergy)
print('循环次数%i, 当前系统能量是:' % (i00 + 1), newEnergy) print('循环次数%i, 当前系统能量是:' % (i00 + 1), newEnergy)
return newS return newS
def Metropolis(S, T): # S是输入的初始状态 T是温度 def Metropolis(S, T): # S是输入的初始状态 T是温度
delta_max = 0.5 * np.pi # 角度最大的变化度数默认是90度也可以调整为其他 delta_max = 0.5 * np.pi # 角度最大的变化度数默认是90度也可以调整为其他
k = 1 # 玻尔兹曼常数 k = 1 # 玻尔兹曼常数
for i in range(S.shape[0]): for i in range(S.shape[0]):
for j in range(S.shape[0]): for j in range(S.shape[0]):
delta = (2 * np.random.random() - 1) * delta_max # 角度变化在-90度到90度之间 delta = (2 * np.random.random() - 1) * delta_max # 角度变化在-90度到90度之间
newAngle = S[i, j] + delta # 新角度 newAngle = S[i, j] + delta # 新角度
energyBefore = getEnergy(i=i, j=j, S=S, angle=None) # 获取该格点的能量 energyBefore = getEnergy(i=i, j=j, S=S, angle=None) # 获取该格点的能量
energyLater = getEnergy(i=i, j=j, S=S, angle=newAngle) # 获取格点变成新角度时的能量 energyLater = getEnergy(i=i, j=j, S=S, angle=newAngle) # 获取格点变成新角度时的能量
alpha = min(1.0, math.exp(-(energyLater - energyBefore)/(k * T))) # 这个接受率对应的是玻尔兹曼分布 alpha = min(1.0, math.exp(-(energyLater - energyBefore)/(k * T))) # 这个接受率对应的是玻尔兹曼分布
if random.uniform(0, 1) <= alpha: if random.uniform(0, 1) <= alpha:
S[i, j] = newAngle # 接受新状态 S[i, j] = newAngle # 接受新状态
else: else:
pass # 保持为上一个状态 pass # 保持为上一个状态
return S return S
def getEnergy(i, j, S, angle=None): # 计算(i,j)位置的能量,为周围四个的相互能之和 def getEnergy(i, j, S, angle=None): # 计算(i,j)位置的能量,为周围四个的相互能之和
width = S.shape[0] width = S.shape[0]
height = S.shape[1] height = S.shape[1]
top_i = i - 1 if i > 0 else width - 1 # 用到周期性边界条件 top_i = i - 1 if i > 0 else width - 1 # 用到周期性边界条件
bottom_i = i + 1 if i < (width - 1) else 0 bottom_i = i + 1 if i < (width - 1) else 0
left_j = j - 1 if j > 0 else height - 1 left_j = j - 1 if j > 0 else height - 1
right_j = j + 1 if j < (height - 1) else 0 right_j = j + 1 if j < (height - 1) else 0
environment = [[top_i, j], [bottom_i, j], [i, left_j], [i, right_j]] environment = [[top_i, j], [bottom_i, j], [i, left_j], [i, right_j]]
energy = 0 energy = 0
if angle == None: if angle == None:
for num_i in range(4): for num_i in range(4):
energy += -np.cos(S[i, j] - S[environment[num_i][0], environment[num_i][1]]) energy += -np.cos(S[i, j] - S[environment[num_i][0], environment[num_i][1]])
else: else:
for num_i in range(4): for num_i in range(4):
energy += -np.cos(angle - S[environment[num_i][0], environment[num_i][1]]) energy += -np.cos(angle - S[environment[num_i][0], environment[num_i][1]])
return energy return energy
def calculateAllEnergy(S): # 计算整个体系的能量 def calculateAllEnergy(S): # 计算整个体系的能量
energy = 0 energy = 0
for i in range(S.shape[0]): for i in range(S.shape[0]):
for j in range(S.shape[1]): for j in range(S.shape[1]):
energy += getEnergy(i, j, S) energy += getEnergy(i, j, S)
return energy/2 # 作用两次要减半 return energy/2 # 作用两次要减半
def plot(S): # 画图 def plot(S): # 画图
X, Y = np.meshgrid(np.arange(0, S.shape[0]), np.arange(0, S.shape[0])) X, Y = np.meshgrid(np.arange(0, S.shape[0]), np.arange(0, S.shape[0]))
U = np.cos(S) U = np.cos(S)
V = np.sin(S) V = np.sin(S)
plt.figure() plt.figure()
plt.quiver(X, Y, U, V, units='inches') plt.quiver(X, Y, U, V, units='inches')
plt.show() plt.show()
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -1,76 +1,76 @@
""" """
This code is supported by the website: https://www.guanjihuan.com This code is supported by the website: https://www.guanjihuan.com
The newest version of this code is on the web page: https://www.guanjihuan.com/archives/1249 The newest version of this code is on the web page: https://www.guanjihuan.com/archives/1249
""" """
import random import random
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import numpy as np import numpy as np
import copy import copy
import math import math
import time import time
def main(): def main():
size = 30 # 体系大小 size = 30 # 体系大小
for T in np.linspace(0.02, 5, 100): for T in np.linspace(0.02, 5, 100):
ising, magnetism = get_one_sample(sizeOfSample=size, temperature=T) ising, magnetism = get_one_sample(sizeOfSample=size, temperature=T)
print('温度=', T, ' 磁矩=', magnetism, ' 总能量=', calculateAllEnergy(ising)) print('温度=', T, ' 磁矩=', magnetism, ' 总能量=', calculateAllEnergy(ising))
plt.plot(T, magnetism, 'o') plt.plot(T, magnetism, 'o')
plt.show() plt.show()
def get_one_sample(sizeOfSample, temperature): def get_one_sample(sizeOfSample, temperature):
newS = np.zeros((sizeOfSample, sizeOfSample)) # 初始状态 newS = np.zeros((sizeOfSample, sizeOfSample)) # 初始状态
magnetism = 0 magnetism = 0
for i00 in range(100): for i00 in range(100):
newS = Metropolis(newS, temperature) newS = Metropolis(newS, temperature)
magnetism = magnetism + abs(sum(sum(np.cos(newS))))/newS.shape[0]**2 magnetism = magnetism + abs(sum(sum(np.cos(newS))))/newS.shape[0]**2
magnetism = magnetism/100 magnetism = magnetism/100
return newS, magnetism return newS, magnetism
def Metropolis(S, T): # S是输入的初始状态 T是温度 def Metropolis(S, T): # S是输入的初始状态 T是温度
k = 1 # 玻尔兹曼常数 k = 1 # 玻尔兹曼常数
for i in range(S.shape[0]): for i in range(S.shape[0]):
for j in range(S.shape[0]): for j in range(S.shape[0]):
newAngle = np.random.randint(-1, 1)*np.pi newAngle = np.random.randint(-1, 1)*np.pi
energyBefore = getEnergy(i=i, j=j, S=S, angle=None) # 获取该格点的能量 energyBefore = getEnergy(i=i, j=j, S=S, angle=None) # 获取该格点的能量
energyLater = getEnergy(i=i, j=j, S=S, angle=newAngle) # 获取格点变成新角度时的能量 energyLater = getEnergy(i=i, j=j, S=S, angle=newAngle) # 获取格点变成新角度时的能量
alpha = min(1.0, math.exp(-(energyLater - energyBefore)/(k * T))) # 这个接受率对应的是玻尔兹曼分布 alpha = min(1.0, math.exp(-(energyLater - energyBefore)/(k * T))) # 这个接受率对应的是玻尔兹曼分布
if random.uniform(0, 1) <= alpha: if random.uniform(0, 1) <= alpha:
S[i, j] = newAngle # 接受新状态 S[i, j] = newAngle # 接受新状态
else: else:
pass # 保持为上一个状态 pass # 保持为上一个状态
return S return S
def getEnergy(i, j, S, angle=None): # 计算(i,j)位置的能量,为周围四个的相互能之和 def getEnergy(i, j, S, angle=None): # 计算(i,j)位置的能量,为周围四个的相互能之和
width = S.shape[0] width = S.shape[0]
height = S.shape[1] height = S.shape[1]
top_i = i - 1 if i > 0 else width - 1 # 用到周期性边界条件 top_i = i - 1 if i > 0 else width - 1 # 用到周期性边界条件
bottom_i = i + 1 if i < (width - 1) else 0 bottom_i = i + 1 if i < (width - 1) else 0
left_j = j - 1 if j > 0 else height - 1 left_j = j - 1 if j > 0 else height - 1
right_j = j + 1 if j < (height - 1) else 0 right_j = j + 1 if j < (height - 1) else 0
environment = [[top_i, j], [bottom_i, j], [i, left_j], [i, right_j]] environment = [[top_i, j], [bottom_i, j], [i, left_j], [i, right_j]]
energy = 0 energy = 0
if angle == None: if angle == None:
for num_i in range(4): for num_i in range(4):
energy += -np.cos(S[i, j] - S[environment[num_i][0], environment[num_i][1]]) energy += -np.cos(S[i, j] - S[environment[num_i][0], environment[num_i][1]])
else: else:
for num_i in range(4): for num_i in range(4):
energy += -np.cos(angle - S[environment[num_i][0], environment[num_i][1]]) energy += -np.cos(angle - S[environment[num_i][0], environment[num_i][1]])
return energy return energy
def calculateAllEnergy(S): # 计算整个体系的能量 def calculateAllEnergy(S): # 计算整个体系的能量
energy = 0 energy = 0
for i in range(S.shape[0]): for i in range(S.shape[0]):
for j in range(S.shape[1]): for j in range(S.shape[1]):
energy += getEnergy(i, j, S) energy += getEnergy(i, j, S)
return energy/2 # 作用两次要减半 return energy/2 # 作用两次要减半
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -1,48 +1,48 @@
""" """
This code is supported by the website: https://www.guanjihuan.com This code is supported by the website: https://www.guanjihuan.com
The newest version of this code is on the web page: https://www.guanjihuan.com/archives/3895 The newest version of this code is on the web page: https://www.guanjihuan.com/archives/3895
""" """
import numpy as np import numpy as np
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from math import * from math import *
import cmath import cmath
import functools import functools
def hamiltonian(k, N, t): # 准一维方格子哈密顿量 def hamiltonian(k, N, t): # 准一维方格子哈密顿量
# 初始化为零矩阵 # 初始化为零矩阵
h00 = np.zeros((N, N), dtype=complex) h00 = np.zeros((N, N), dtype=complex)
h01 = np.zeros((N, N), dtype=complex) h01 = np.zeros((N, N), dtype=complex)
for i in range(N-1): # 原胞内的跃迁h00 for i in range(N-1): # 原胞内的跃迁h00
h00[i, i+1] = t h00[i, i+1] = t
h00[i+1, i] = t h00[i+1, i] = t
for i in range(N): # 原胞间的跃迁h01 for i in range(N): # 原胞间的跃迁h01
h01[i, i] = t h01[i, i] = t
matrix = h00 + h01*cmath.exp(1j*k) + h01.transpose().conj()*cmath.exp(-1j*k) matrix = h00 + h01*cmath.exp(1j*k) + h01.transpose().conj()*cmath.exp(-1j*k)
return matrix return matrix
def main(): def main():
H_k = functools.partial(hamiltonian, N=10, t=1) H_k = functools.partial(hamiltonian, N=10, t=1)
k = np.linspace(-pi, pi, 300) k = np.linspace(-pi, pi, 300)
plot_bands_one_dimension(k, H_k) plot_bands_one_dimension(k, H_k)
def plot_bands_one_dimension(k, hamiltonian): def plot_bands_one_dimension(k, hamiltonian):
dim = hamiltonian(0).shape[0] dim = hamiltonian(0).shape[0]
dim_k = k.shape[0] dim_k = k.shape[0]
eigenvalue_k = np.zeros((dim_k, dim)) eigenvalue_k = np.zeros((dim_k, dim))
i0 = 0 i0 = 0
for k0 in k: for k0 in k:
matrix0 = hamiltonian(k0) matrix0 = hamiltonian(k0)
eigenvalue, eigenvector = np.linalg.eig(matrix0) eigenvalue, eigenvector = np.linalg.eig(matrix0)
eigenvalue_k[i0, :] = np.sort(np.real(eigenvalue[:])) eigenvalue_k[i0, :] = np.sort(np.real(eigenvalue[:]))
i0 += 1 i0 += 1
for dim0 in range(dim): for dim0 in range(dim):
plt.plot(k, eigenvalue_k[:, dim0], '-k') plt.plot(k, eigenvalue_k[:, dim0], '-k')
plt.show() plt.show()
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -1,129 +1,129 @@
""" """
This code is supported by the website: https://www.guanjihuan.com This code is supported by the website: https://www.guanjihuan.com
The newest version of this code is on the web page: https://www.guanjihuan.com/archives/3888 The newest version of this code is on the web page: https://www.guanjihuan.com/archives/3888
""" """
import numpy as np import numpy as np
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import time import time
def matrix_00(width=10): # 电极元胞内跃迁width不赋值时默认为10 def matrix_00(width=10): # 电极元胞内跃迁width不赋值时默认为10
h00 = np.zeros((width, width)) h00 = np.zeros((width, width))
for width0 in range(width-1): for width0 in range(width-1):
h00[width0, width0+1] = 1 h00[width0, width0+1] = 1
h00[width0+1, width0] = 1 h00[width0+1, width0] = 1
return h00 return h00
def matrix_01(width=10): # 电极元胞间跃迁width不赋值时默认为10 def matrix_01(width=10): # 电极元胞间跃迁width不赋值时默认为10
h01 = np.identity(width) h01 = np.identity(width)
return h01 return h01
def matrix_LC(width=10, length=300): # 左电极跳到中心区 def matrix_LC(width=10, length=300): # 左电极跳到中心区
h_LC = np.zeros((width, width*length)) h_LC = np.zeros((width, width*length))
for width0 in range(width): for width0 in range(width):
h_LC[width0, width0] = 1 h_LC[width0, width0] = 1
return h_LC return h_LC
def matrix_CR(width=10, length=300): # 中心区跳到右电极 def matrix_CR(width=10, length=300): # 中心区跳到右电极
h_CR = np.zeros((width*length, width)) h_CR = np.zeros((width*length, width))
for width0 in range(width): for width0 in range(width):
h_CR[width*(length-1)+width0, width0] = 1 h_CR[width*(length-1)+width0, width0] = 1
return h_CR return h_CR
def matrix_center(width=10, length=300): # 中心区哈密顿量 def matrix_center(width=10, length=300): # 中心区哈密顿量
hamiltonian = np.zeros((width*length, width*length)) hamiltonian = np.zeros((width*length, width*length))
for length0 in range(length-1): for length0 in range(length-1):
for width0 in range(width): for width0 in range(width):
hamiltonian[width*length0+width0, width*(length0+1)+width0] = 1 # 长度方向跃迁 hamiltonian[width*length0+width0, width*(length0+1)+width0] = 1 # 长度方向跃迁
hamiltonian[width*(length0+1)+width0, width*length0+width0] = 1 hamiltonian[width*(length0+1)+width0, width*length0+width0] = 1
for length0 in range(length): for length0 in range(length):
for width0 in range(width-1): for width0 in range(width-1):
hamiltonian[width*length0+width0, width*length0+width0+1] = 1 # 宽度方向跃迁 hamiltonian[width*length0+width0, width*length0+width0+1] = 1 # 宽度方向跃迁
hamiltonian[width*length0+width0+1, width*length0+width0] = 1 hamiltonian[width*length0+width0+1, width*length0+width0] = 1
# 中间加势垒 # 中间加势垒
for j0 in range(6): for j0 in range(6):
for i0 in range(6): for i0 in range(6):
hamiltonian[width*(int(length/2)-3+j0)+int(width/2)-3+i0, width*(int(length/2)-3+j0)+int(width/2)-3+i0]= 1e8 hamiltonian[width*(int(length/2)-3+j0)+int(width/2)-3+i0, width*(int(length/2)-3+j0)+int(width/2)-3+i0]= 1e8
return hamiltonian return hamiltonian
def main(): def main():
start_time = time.time() start_time = time.time()
fermi_energy = 0 fermi_energy = 0
width = 60 width = 60
length = 100 length = 100
h00 = matrix_00(width) h00 = matrix_00(width)
h01 = matrix_01(width) h01 = matrix_01(width)
G_n = Green_n(fermi_energy+1j*1e-9, h00, h01, width, length) G_n = Green_n(fermi_energy+1j*1e-9, h00, h01, width, length)
# 下面是提取数据并画图 # 下面是提取数据并画图
direction_x = np.zeros((width, length)) direction_x = np.zeros((width, length))
direction_y = np.zeros((width, length)) direction_y = np.zeros((width, length))
for length0 in range(length-1): for length0 in range(length-1):
for width0 in range(width): for width0 in range(width):
direction_x[width0, length0] = G_n[width*length0+width0, width*(length0+1)+width0] direction_x[width0, length0] = G_n[width*length0+width0, width*(length0+1)+width0]
for length0 in range(length): for length0 in range(length):
for width0 in range(width-1): for width0 in range(width-1):
direction_y[width0, length0] = G_n[width*length0+width0, width*length0+width0+1] direction_y[width0, length0] = G_n[width*length0+width0, width*length0+width0+1]
# print(direction_x) # print(direction_x)
# print(direction_y) # print(direction_y)
X, Y = np.meshgrid(range(length), range(width)) X, Y = np.meshgrid(range(length), range(width))
plt.quiver(X, Y, direction_x, direction_y) plt.quiver(X, Y, direction_x, direction_y)
plt.show() plt.show()
end_time = time.time() end_time = time.time()
print('运行时间=', end_time-start_time) print('运行时间=', end_time-start_time)
def transfer_matrix(fermi_energy, h00, h01, dim): # 转移矩阵T。dim是传递矩阵h00和h01的维度 def transfer_matrix(fermi_energy, h00, h01, dim): # 转移矩阵T。dim是传递矩阵h00和h01的维度
transfer = np.zeros((2*dim, 2*dim), dtype=complex) transfer = np.zeros((2*dim, 2*dim), dtype=complex)
transfer[0:dim, 0:dim] = np.dot(np.linalg.inv(h01), fermi_energy*np.identity(dim)-h00) # np.dot()等效于np.matmul() transfer[0:dim, 0:dim] = np.dot(np.linalg.inv(h01), fermi_energy*np.identity(dim)-h00) # np.dot()等效于np.matmul()
transfer[0:dim, dim:2*dim] = np.dot(-1*np.linalg.inv(h01), h01.transpose().conj()) transfer[0:dim, dim:2*dim] = np.dot(-1*np.linalg.inv(h01), h01.transpose().conj())
transfer[dim:2*dim, 0:dim] = np.identity(dim) transfer[dim:2*dim, 0:dim] = np.identity(dim)
transfer[dim:2*dim, dim:2*dim] = 0 # a:b代表 a <= x < b transfer[dim:2*dim, dim:2*dim] = 0 # a:b代表 a <= x < b
return transfer # 返回转移矩阵 return transfer # 返回转移矩阵
def green_function_lead(fermi_energy, h00, h01, dim): # 电极的表面格林函数 def green_function_lead(fermi_energy, h00, h01, dim): # 电极的表面格林函数
transfer = transfer_matrix(fermi_energy, h00, h01, dim) transfer = transfer_matrix(fermi_energy, h00, h01, dim)
eigenvalue, eigenvector = np.linalg.eig(transfer) eigenvalue, eigenvector = np.linalg.eig(transfer)
ind = np.argsort(np.abs(eigenvalue)) ind = np.argsort(np.abs(eigenvalue))
temp = np.zeros((2*dim, 2*dim))*(1+0j) temp = np.zeros((2*dim, 2*dim))*(1+0j)
i0 = 0 i0 = 0
for ind0 in ind: for ind0 in ind:
temp[:, i0] = eigenvector[:, ind0] temp[:, i0] = eigenvector[:, ind0]
i0 += 1 i0 += 1
s1 = temp[dim:2*dim, 0:dim] s1 = temp[dim:2*dim, 0:dim]
s2 = temp[0:dim, 0:dim] s2 = temp[0:dim, 0:dim]
s3 = temp[dim:2*dim, dim:2*dim] s3 = temp[dim:2*dim, dim:2*dim]
s4 = temp[0:dim, dim:2*dim] s4 = temp[0:dim, dim:2*dim]
right_lead_surface = np.linalg.inv(fermi_energy*np.identity(dim)-h00-np.dot(np.dot(h01, s2), np.linalg.inv(s1))) right_lead_surface = np.linalg.inv(fermi_energy*np.identity(dim)-h00-np.dot(np.dot(h01, s2), np.linalg.inv(s1)))
left_lead_surface = np.linalg.inv(fermi_energy*np.identity(dim)-h00-np.dot(np.dot(h01.transpose().conj(), s3), np.linalg.inv(s4))) left_lead_surface = np.linalg.inv(fermi_energy*np.identity(dim)-h00-np.dot(np.dot(h01.transpose().conj(), s3), np.linalg.inv(s4)))
return right_lead_surface, left_lead_surface # 返回右电极的表面格林函数和左电极的表面格林函数 return right_lead_surface, left_lead_surface # 返回右电极的表面格林函数和左电极的表面格林函数
def self_energy_lead(fermi_energy, h00, h01, width, length): # 电极的自能 def self_energy_lead(fermi_energy, h00, h01, width, length): # 电极的自能
h_LC = matrix_LC(width, length) h_LC = matrix_LC(width, length)
h_CR = matrix_CR(width, length) h_CR = matrix_CR(width, length)
right_lead_surface, left_lead_surface = green_function_lead(fermi_energy, h00, h01, width) right_lead_surface, left_lead_surface = green_function_lead(fermi_energy, h00, h01, width)
right_self_energy = np.dot(np.dot(h_CR, right_lead_surface), h_CR.transpose().conj()) right_self_energy = np.dot(np.dot(h_CR, right_lead_surface), h_CR.transpose().conj())
left_self_energy = np.dot(np.dot(h_LC.transpose().conj(), left_lead_surface), h_LC) left_self_energy = np.dot(np.dot(h_LC.transpose().conj(), left_lead_surface), h_LC)
return right_self_energy, left_self_energy # 返回右电极的自能和左电极的自能 return right_self_energy, left_self_energy # 返回右电极的自能和左电极的自能
def Green_n(fermi_energy, h00, h01, width, length): # 计算G_n def Green_n(fermi_energy, h00, h01, width, length): # 计算G_n
right_self_energy, left_self_energy = self_energy_lead(fermi_energy, h00, h01, width, length) right_self_energy, left_self_energy = self_energy_lead(fermi_energy, h00, h01, width, length)
hamiltonian = matrix_center(width, length) hamiltonian = matrix_center(width, length)
green = np.linalg.inv(fermi_energy*np.identity(width*length)-hamiltonian-left_self_energy-right_self_energy) green = np.linalg.inv(fermi_energy*np.identity(width*length)-hamiltonian-left_self_energy-right_self_energy)
right_self_energy = (right_self_energy - right_self_energy.transpose().conj())*1j right_self_energy = (right_self_energy - right_self_energy.transpose().conj())*1j
left_self_energy = (left_self_energy - left_self_energy.transpose().conj())*1j left_self_energy = (left_self_energy - left_self_energy.transpose().conj())*1j
G_n = np.imag(np.dot(np.dot(green, left_self_energy), green.transpose().conj())) G_n = np.imag(np.dot(np.dot(green, left_self_energy), green.transpose().conj()))
return G_n return G_n
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -55,13 +55,24 @@ def main():
# lead2 lead3 # lead2 lead3
# lead1(L) lead4(R) # lead1(L) lead4(R)
# lead6 lead5 # lead6 lead5
transmission_matrix = guan.calculate_six_terminal_transmission_matrix(fermi_energy, h00_for_lead_4=lead_h00, h01_for_lead_4=lead_h01, h00_for_lead_2=lead_h00, h01_for_lead_2=lead_h01, center_hamiltonian=center_hamiltonian, width=width, length=length, internal_degree=1, moving_step_of_leads=0)
transmission_12_array.append(transmission_matrix[0, 1]) transmission_12, transmission_13, transmission_14, transmission_15, transmission_16 = guan.calculate_six_terminal_transmissions_from_lead_1(fermi_energy, h00_for_lead_4=lead_h00, h01_for_lead_4=lead_h01, h00_for_lead_2=lead_h00, h01_for_lead_2=lead_h01, center_hamiltonian=center_hamiltonian, width=width, length=length, internal_degree=1, moving_step_of_leads=0)
transmission_13_array.append(transmission_matrix[0, 2]) transmission_12_array.append(transmission_12)
transmission_14_array.append(transmission_matrix[0, 3]) transmission_13_array.append(transmission_13)
transmission_15_array.append(transmission_matrix[0, 4]) transmission_14_array.append(transmission_14)
transmission_16_array.append(transmission_matrix[0, 5]) transmission_15_array.append(transmission_15)
transmission_1_all_array.append(transmission_matrix[0, 1]+transmission_matrix[0, 2]+transmission_matrix[0, 3]+transmission_matrix[0, 4]+transmission_matrix[0, 5]) transmission_16_array.append(transmission_16)
transmission_1_all_array.append(\
transmission_12+transmission_13+transmission_14+transmission_15+transmission_16)
# transmission_matrix = guan.calculate_six_terminal_transmission_matrix(fermi_energy, h00_for_lead_4=lead_h00, h01_for_lead_4=lead_h01, h00_for_lead_2=lead_h00, h01_for_lead_2=lead_h01, center_hamiltonian=center_hamiltonian, width=width, length=length, internal_degree=1, moving_step_of_leads=0)
# transmission_12_array.append(transmission_matrix[0, 1])
# transmission_13_array.append(transmission_matrix[0, 2])
# transmission_14_array.append(transmission_matrix[0, 3])
# transmission_15_array.append(transmission_matrix[0, 4])
# transmission_16_array.append(transmission_matrix[0, 5])
# transmission_1_all_array.append(transmission_matrix[0, 1]+transmission_matrix[0, 2]+transmission_matrix[0, 3]+transmission_matrix[0, 4]+transmission_matrix[0, 5])
guan.plot(fermi_energy_array, transmission_12_array, xlabel='Fermi energy', ylabel='Transmission_12') guan.plot(fermi_energy_array, transmission_12_array, xlabel='Fermi energy', ylabel='Transmission_12')
guan.plot(fermi_energy_array, transmission_13_array, xlabel='Fermi energy', ylabel='Transmission_13') guan.plot(fermi_energy_array, transmission_13_array, xlabel='Fermi energy', ylabel='Transmission_13')
guan.plot(fermi_energy_array, transmission_14_array, xlabel='Fermi energy', ylabel='Transmission_14') guan.plot(fermi_energy_array, transmission_14_array, xlabel='Fermi energy', ylabel='Transmission_14')
@ -69,7 +80,7 @@ def main():
guan.plot(fermi_energy_array, transmission_16_array, xlabel='Fermi energy', ylabel='Transmission_16') guan.plot(fermi_energy_array, transmission_16_array, xlabel='Fermi energy', ylabel='Transmission_16')
guan.plot(fermi_energy_array, transmission_1_all_array, xlabel='Fermi energy', ylabel='Transmission_1_all') guan.plot(fermi_energy_array, transmission_1_all_array, xlabel='Fermi energy', ylabel='Transmission_1_all')
end_time = time.time() end_time = time.time()
print('运行时间=', end_time-start_time) print('运行时间(分)=', (end_time-start_time)/60)
if __name__ == '__main__': if __name__ == '__main__':