{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Juliaで学ぶタイトバインディング模型とトポロジカル物質\n",
"## 4. グラフェンと呼ばれるタイトバインディング模型:ジグザグ版\n",
"グラフェンをタイトバインディング模型で扱う。ここで、有限のグラフェンを考えると、端状態が出てくるのを見る。なお、このノートで考える端はジグザグ型とする。もう一つの端の形であるアームチェア型については、次回のノートで扱う。\n",
"### 4.1 グラフェン\n",
"これまで単純な正方格子模型を考えてきたので、今度は六角格子を考える。\n",
"六角格子として最も有名なのはグラフェン(graphene)である。ちなみに、日本語ではグラフェンと呼ぶことが多いが、英語での発音はグラフィーンに近い。\n",
"\n",
"\n",
"なお、六角格子は\n",
"Twitterアカウント@genkurokiさんの\n",
"https://gist.github.com/genkuroki/e1a86f3eb9d4b61dd0d62b7fb0a1250c\n",
"を参考にして描いている。\n",
"\n",
" \n",
" \n",
"#### 結晶構造\n",
"グラフェンの結晶構造は六角形で、以下のような形をしている。"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"using Plots\n",
"\n",
"a = 0.5\n",
"x0 = (i*sqrt(3)*a for i in -3:3)\n",
"x1 = (i*sqrt(3)*a + sqrt(3)*a/2 for i in -4:3)\n",
"y0 = ( 2j *1.5*a for j in -2:2)\n",
"y1 = ((2j+1)*1.5*a for j in -2:1)\n",
"\n",
"c = \"red\"\n",
"lw = 0.5\n",
"ls = :dash\n",
"\n",
"plot(size=(500,500), legend=false)\n",
"\n",
"for y in y0\n",
" for x in x0\n",
" plot!([x, x ], [y, y+a ], color=c, lw=lw, ls=ls)\n",
" plot!([x, x-sqrt(3)*a/2], [y, y-a/2], color=c, lw=lw, ls=ls)\n",
" plot!([x, x+sqrt(3)*a/2], [y, y-a/2], color=c, lw=lw, ls=ls)\n",
" end\n",
"end\n",
"\n",
"for y in y1\n",
" for x in x1\n",
" plot!([x, x ], [y, y+a ], color=c, lw=lw, ls=ls)\n",
" plot!([x, x-sqrt(3)*a/2], [y, y-a/2], color=c, lw=lw, ls=ls)\n",
" plot!([x, x+sqrt(3)*a/2], [y, y-a/2], color=c, lw=lw, ls=ls)\n",
" end\n",
"end\n",
"\n",
"plot!(xlim=(-3,3), ylim=(-2.5,3))\n",
"plot!(aspect_ratio=:equal)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"グラフェンは、このような構造で最近接原子同士のホッピングが有限であり、それ以外はゼロとなっている。この結晶構造をタイトバインディング模型として考えたい。まず、このハチの巣構造をよく眺めてみると、二種類の原子があることがわかる。"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"using Plots\n",
"\n",
"a = 0.5\n",
"x0 = (i*sqrt(3)*a for i in -2:2)\n",
"x1 = (i*sqrt(3)*a + sqrt(3)*a/2 for i in -3:1)\n",
"y0 = ( 2j *1.5*a for j in -1:1)\n",
"y1 = ((2j+1)*1.5*a for j in -1:0.5)\n",
"\n",
"c = \"red\"\n",
"b = \"blue\"\n",
"lw = 0.5\n",
"ls = :dash\n",
"\n",
"plot(size=(500,500), legend=false)\n",
"\n",
"for y in y0\n",
" for x in x0\n",
" plot!([x, x ], [y, y+a ], color=c, lw=lw, ls=ls)\n",
" plot!([x],[y],marker=:circle,color=c)\n",
" plot!([x-sqrt(3)*a/2], [y-a/2],marker=:circle,color=b)\n",
" plot!([x, x-sqrt(3)*a/2], [y, y-a/2], color=c, lw=lw)\n",
" plot!([x, x+sqrt(3)*a/2], [y, y-a/2], color=c, lw=lw,ls=ls)\n",
" end\n",
"end\n",
"\n",
"for y in y1\n",
" for x in x1\n",
" plot!([x, x ], [y, y+a ], color=c, lw=lw, ls=ls)\n",
" plot!([x, x-sqrt(3)*a/2], [y, y-a/2], color=c, lw=lw)\n",
" plot!([x],[y],marker=:circle,color=c)\n",
" plot!([x-sqrt(3)*a/2], [y-a/2],marker=:circle,color=b)\n",
" plot!([x, x+sqrt(3)*a/2], [y, y-a/2], color=c, lw=lw, ls=ls)\n",
" end\n",
"end\n",
"\n",
"\n",
"plot!(aspect_ratio=:equal)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"六角形の一番上の原子を赤色、その横の原子を青色とした。このとき、左下が青色右上が赤色の線分が周期的に並んでいるとみなすことができる。この二つの原子の塊を「ユニットセル」と呼ぶ。\n",
"赤色を軌道1、青色を軌道2とする。それぞれの原子は、\n",
"- 赤色:x方向に+1ずれた青色とy方向に+1ずれた青色、そして、同一ユニットセル内の青色と接続\n",
"- 青色:x方向に-1ずれた赤色とy方向に-1ずれた赤色、そして、同一ユニットセル内の赤色と接続\n",
"\n",
"となっている。ここで、原子にラベルをつける。考えているユニットセルを(ix,iy)とし、軌道の情報も含めて、(a,ix,iy)とする。このとき、\n",
"- 赤色(1,ix,iy):(2,ix+1,iy)、(2,ix,iy+1)、(2,ix,iy)\n",
"- 青色(2,ix,iy):(1,ix-1,iy)、(1,ix,iy-1)、(1,ix,iy)\n",
"\n",
"というラベルを割り当てることができる。\n",
"この割り当てをもちいて、ハミルトニアンを作ると、"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"calc_HGraphene (generic function with 1 method)"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"function calc_HGraphene(Nx,Ny,μ)\n",
" N = Nx*Ny*2\n",
" mat_Htb = zeros(Float64,N,N) \n",
" mat_Htb += (-μ)*Matrix(I,N,N) #eye(N)\n",
" t = 1.0\n",
" for ix =1:Nx\n",
" for iy=1:Ny \n",
" for dx in -1:1\n",
" for dy in -1:1\n",
" jx = ix + dx\n",
" \n",
" jx += ifelse(jx > Nx,-Nx,0)\n",
" jx += ifelse(jx < 1,Nx,0)\n",
" \n",
" jy = iy + dy\n",
" jy += ifelse(jy > Ny,-Ny,0)\n",
" jy += ifelse(jy < 1,Ny,0)\n",
" \n",
" \n",
" for a=1:2\n",
" b = ifelse(a ==1,2,1)\n",
" ii = ((iy-1)*Nx+ix-1)*2+a\n",
" jj = ((jy-1)*Nx+jx-1)*2+b\n",
"\n",
" if dx == 0 && dy == 0\n",
" mat_Htb[ii,jj] = t\n",
" elseif dx == +1 && dy==0 && a ==1\n",
" mat_Htb[ii,jj] = t\n",
" elseif dx == 0 && dy == 1 && a ==1\n",
" mat_Htb[ii,jj] = t\n",
" elseif dx == -1 && dy ==0 && a ==2\n",
" mat_Htb[ii,jj] = t\n",
" elseif dx ==0 && dy == -1 && a ==2\n",
" mat_Htb[ii,jj] = t\n",
" end\n",
" end\n",
" \n",
"\n",
" end\n",
" end\n",
" end\n",
" end\n",
" \n",
" \n",
" return mat_Htb\n",
"end"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"となる。これを対角化しヒストグラムを見てみると、"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"using LinearAlgebra\n",
"Nx = 40\n",
"Ny = 40\n",
"μ = 0\n",
"mat_H = calc_HGraphene(Nx,Ny,μ)\n",
"#println(mat_H)\n",
"energy,mat_v = eigen(mat_H)\n",
"histogram(energy,bins=100)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"これを見ると、ゼロエネルギーの固有値がとても少ないことがわかる。この原因を探るために、片方をフーリエ変換してみよう。$x$方向だけフーリエ変換することを考える。ここで、コード中のdxを用いて$\\exp(i kx dx)$とすれば、簡単にフーリエ変換を実行できる。グラフェンの場合、cosやsinではなく、$\\exp(i kx dx)$のような項が残り、行列は複素数のエルミート行列となる。Juliaでは、実数でも複素数でもeigで対角化をすることができる。ハミルトニアンは、"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"calc_HGraphenekx (generic function with 1 method)"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"function calc_HGraphenekx(kx,Ny,μ)\n",
" N = Ny*2\n",
" mat_Htb = zeros(Complex{Float64},N,N) \n",
" mat_Htb += (-μ)*Matrix(I,N,N)#eye(N)\n",
" t = 1.0\n",
" for iy=1:Ny \n",
" for dy in -1:1 \n",
" jy = iy + dy\n",
" jy += ifelse(jy > Ny,-Ny,0)\n",
" jy += ifelse(jy < 1,Ny,0)\n",
" \n",
" for a=1:2\n",
" b = ifelse(a ==1,2,1)\n",
" ii = (iy-1)*2+a\n",
" jj = (jy-1)*2+b\n",
"\n",
" if dy == 0 && a == 1\n",
" mat_Htb[ii,jj] = t+t*exp(im*kx) \n",
" elseif dy == 1 && a ==1\n",
" mat_Htb[ii,jj] = t\n",
" elseif dy ==0 && a ==2\n",
" mat_Htb[ii,jj] = t+t*exp(-im*kx)\n",
" elseif dy == -1 && a ==2\n",
" mat_Htb[ii,jj] = t\n",
" end\n",
" end\n",
" \n",
"\n",
" end\n",
" end\n",
" \n",
" \n",
" return mat_Htb\n",
"end"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"となる。この模型のバンドを描いてみると、"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"μ=0.0\n",
"Ny = 50\n",
"nkx = 100\n",
"vkx = range(-π,π,length = nkx)\n",
"ep = zeros(Float64,nkx,Ny*2)\n",
"cnt = 0\n",
"for kx in vkx \n",
" cnt += 1\n",
" mat_H = calc_HGraphenekx(kx,Ny,μ)\n",
" energy,mat_v = eigen(mat_H)\n",
" for i=1:Ny*2\n",
" #println(energy[i])\n",
" ep[cnt,i] = energy[i]\n",
" end\n",
"end\n",
"plot(vkx,ep)\n",
"plot!(legend=false)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"となる。これをみると、特定の波数においてゼロエネルギーになっていることがわかる。\n",
"さらにkyについてもフーリエ変換してみよう。ここで、y方向の原子の間隔は、x方向の原子の間隔\n",
"よりも短いことに注意しよう。青色の三角形を考えたとき、x方向の原子の間隔ははこの三角形の辺の長さに等しいが、y方向の長さは頂点から辺に垂直におろした線分の長さに等しいので、$\\sqrt{3}/2$倍だけ長さが短い。ハミルトニアンは"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"calc_HGraphenekxky (generic function with 1 method)"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"function calc_HGraphenekxky(kx,ky,μ)\n",
" N = 2\n",
" mat_Htb = zeros(Complex{Float64},N,N) \n",
" mat_Htb += (-μ)*Matrix(I,N,N)#eye(N)\n",
" t = 1.0\n",
" c = sqrt(3)/2\n",
"# for iy=1:Ny \n",
"# for dy in -1:1 \n",
"# jy = iy + dy\n",
"# jy += ifelse(jy > Ny,-Ny,0)\n",
"# jy += ifelse(jy < 1,Ny,0)\n",
" \n",
" for a=1:2\n",
" b = ifelse(a ==1,2,1)\n",
" ii = a\n",
" jj = b\n",
"\n",
" if a == 1\n",
" mat_Htb[ii,jj] = t+t*exp(im*kx)+t*exp(im*ky+c) \n",
"# elseif dy == 1 && a ==1\n",
"# mat_Htb[ii,jj] = t\n",
" elseif a ==2\n",
" mat_Htb[ii,jj] = t+t*exp(-im*kx)+t*exp(-im*ky*c)\n",
"# elseif dy == -1 && a ==2\n",
"# mat_Htb[ii,jj] = t\n",
" end\n",
" end\n",
" \n",
"\n",
"# end\n",
"# end\n",
" \n",
" \n",
" return mat_Htb\n",
"end"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"となるが、これは"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2×2 Matrix{ComplexF64}:\n",
" 0.0+0.0im 0.141175+2.76362im\n",
" 1.21204-1.78606im 0.0+0.0im"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
" calc_HGraphenekxky(1.0,2.2,μ)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"であり、対角要素をもたない2x2の行列なので簡単に固有値を求めることができ、\n",
"$$\n",
"E = \\pm t \\sqrt{(1 + e^{i k_x } + e^{i k_y \\sqrt{3}/2})(1 + e^{-i k_x } + e^{-i k_y\\sqrt{3}/2)}}\n",
"$$\n",
"とである。整理すると\n",
"$$\n",
"E = \\pm t \\sqrt{1 + e^{i k_x} + e^{-i k_x} + 1+ e^{i k_y \\sqrt{3}/2} + e^{-i k_y \\sqrt{3}/2} + e^{i k_x} e^{- i k_y \\sqrt{3}/2} + e^{i k_y \\sqrt{3}/2} e^{- i k_x} + 1}\n",
"$$\n",
"$$\n",
"E = \\pm \\sqrt{3 + 2 \\cos k_x + 2 \\cos (k_y \\sqrt{3}/2) + 2 \\cos (k_x-k_y \\sqrt{3}/2)}\n",
"$$\n",
"となる。このエネルギーをプロットしてみると、"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"\n",
"f(kx,ky) = sqrt(3 + 2*cos(kx)+2*cos(ky*sqrt(3)/2) + 2*cos(kx-ky*sqrt(3)/2))\n",
"\n",
"x = -2π:2π/100:2π\n",
"y = -2π:2π/100:2π\n",
"z = [f(i,j) for i in x, j in y]'\n",
"\n",
"plot(x,y,z)\n",
"plot!(aspect_ratio=:equal)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"プロットが傾いているようにみえるのは、最初にタイトバインディング模型を考えたときのix軸とiy軸が直交してないためである。x方向は青色の横方向であるが、y方向は青色の三角形の頂点の方向に傾いており、60度傾いている。したがって、この60度分を戻してやると"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"f(kx,ky) = sqrt(3 + 2*cos(kx+ky/2)+2*cos(ky) + 2*cos(kx+ky/2-ky))\n",
"\n",
"x = -2π:2π/100:2π\n",
"y = -2π:2π/100:2π\n",
"z = [f(i,j) for i in x, j in y]'\n",
"\n",
"plot(x,y,z)\n",
"plot!(aspect_ratio=:equal)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"のようになり、結晶の六回対称性を持ったエネルギー分散が現れる。ここで、エネルギーがゼロとなっているのは、等高線が三角形になっている部分の中心である。そして、2x2の固有値は二つあり、その二つの固有値はこの中心で両方ともゼロエネルギーになっている。この点を「ディラック点」と呼ぶ。\n",
"\n",
"### 4.2 端状態\n",
"最後に、片方だけフーリエ変換をした模型に戻る。この模型のハミルトニアンには周期的境界条件が入っていた。この周期的境界条件はifelse文によって表現されている。この部分をコメントアウトすることで、y方向に垂直な端が導入されることになる。つまり、有限サイズのグラフェンとなる。このときのハミルトニアンは"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"calc_HGraphenekx_w (generic function with 1 method)"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"function calc_HGraphenekx_w(kx,Ny,μ)\n",
" N = Ny*2\n",
" mat_Htb = zeros(ComplexF64,N,N) \n",
" mat_Htb += (-μ)*Matrix(I,N,N)#eye(N)\n",
" t = 1.0\n",
" for iy=1:Ny \n",
" for dy in -1:1 \n",
" jy = iy + dy\n",
" #jy += ifelse(jy > Ny,-Ny,0)\n",
" #jy += ifelse(jy < 1,Ny,0)\n",
" \n",
" for a=1:2\n",
" b = ifelse(a ==1,2,1)\n",
" ii = (iy-1)*2+a\n",
" jj = (jy-1)*2+b\n",
" if 1 <= jy <= Ny\n",
" if dy == 0 && a == 1\n",
" mat_Htb[ii,jj] = t+t*exp(im*kx) \n",
" elseif dy == 1 && a ==1\n",
" mat_Htb[ii,jj] = t\n",
" elseif dy ==0 && a ==2\n",
" mat_Htb[ii,jj] = t+t*exp(-im*kx)\n",
" elseif dy == -1 && a ==2\n",
" mat_Htb[ii,jj] = t\n",
" end\n",
" end\n",
" end\n",
" \n",
"\n",
" end\n",
" end\n",
" \n",
" \n",
" return mat_Htb\n",
"end"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"であり、固有値を計算してみると、"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"μ=0.0\n",
"Ny = 50\n",
"nkx = 100\n",
"vkx = range(-π,π,length=nkx)\n",
"ep = zeros(Float64,nkx,Ny*2)\n",
"cnt = 0\n",
"for kx in vkx \n",
" cnt += 1\n",
" mat_H = calc_HGraphenekx_w(kx,Ny,μ)\n",
" energy,mat_v = eigen(mat_H)\n",
" for i=1:Ny*2\n",
" #println(energy[i])\n",
" ep[cnt,i] = energy[i]\n",
" end\n",
"end\n",
"plot(vkx,ep)\n",
"plot!(legend=false)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"となって、ゼロエネルギーに新しい固有値が出現している。特にフラットになっている。\n",
"どのような波動関数になっているかを調べるために、$k_x = \\pi$近傍の固有関数をプロットしてみると、 "
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"kx = π-0.1\n",
"Ny = 50\n",
"mat_H = calc_HGraphenekx_w(kx,Ny,μ)\n",
"energy,mat_v = eigen(mat_H)\n",
"yv = []\n",
"ψ1 = []\n",
"ψ2 = []\n",
"for i in 1:Ny\n",
" push!(yv,i)\n",
" push!(ψ1,mat_v[2*i,Ny])\n",
" push!(ψ2,mat_v[2*i-1,Ny+1])\n",
"end\n",
"plot(yv,[real.(ψ1),imag.(ψ1),real.(ψ2),imag.(ψ2)],label=[\"1:Real\",\"1:Imag\",\"2:Real\",\"2:Imag\"])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"となる。ここで、エネルギーが縮退しているので、両方の固有値の波動関数をプロットしてみた。わかるのは、この二つの波動関数は、ともに、端に局在している、ということである。なお、今考えている端は、最初に図を描いた六角格子の一番上と同じ状況になっており、この端があるグラフェンのことを「ジグザググラフェン」と呼ぶ。次のノートでは、もう一つのグラフェンである、「アームチェアグラフェン」について調べてみる。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.6.2",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}