#################################################################
## 無限に深い量子井戸の波動関数
#################################################################
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
#図全体
fig = plt.figure(figsize=(8, 8))
#全体設定
plt.rcParams['font.family'] = 'Times New Roman' #フォント
plt.rcParams['font.size'] = 24 #フォントサイズ
plt.rcParams["mathtext.fontset"] = 'cm' #数式用フォント
#カラーリストの取得
colors = plt.rcParams['axes.prop_cycle'].by_key()['color']
#################################################################
## 物理定数
#################################################################
#プランク定数
h = 6.62607015 * 1.0E-34
hbar = h / (2.0 * np.pi)
#電子の質量
me = 9.1093837015 * 1.0E-31
#電子ボルト
eV = 1.602176634 * 1.0E-19
#ナノメートル
nm = 1E-9
#虚数単位
I = 0.0 + 1.0j
#################################################################
## 物理系の設定
#################################################################
#量子井戸の幅(m)
L = 1.0 * nm
#固有関数
def verphi(n, x):
kn = np.pi * (n + 1) / L
return np.sqrt(2.0 / L) * np.sin( kn * ( x + L / 2.0 ) )
#固有エネルギー(eV)
def Energy(n):
kn = np.pi * (n + 1) / L
return hbar**2 * kn**2 / (2.0 * me)
#波動関数
def phi(n, x, t):
kn = np.pi * (n + 1) / L
omega = hbar * kn**2 / (2.0 * me)
return verphi(n,x) * np.exp(- I * omega * t)
#状態数
NS = 4
#固有エネルギーの表示(eV)
for n in range( NS + 1 ):
if( n == 0 ): text = "基底状態"
else: text = "第" + str(n) + "励起状態"
print( text + ":" + str(Energy( n )/eV) + " [eV]" )
#計算時間の幅
ts = 0
te = 1
#基底状態の周期
T0 = 2.0 * np.pi * hbar / Energy(0)
print( "基底状態の周期:" + str(T0) + " [s]" )
#########################################################################
# 波動関数 アニメーション
#########################################################################
#時間間隔
dt = T0 / (te - ts + 1)
#描画範囲
x_min = -L/2
x_max = L/2
#描画区間数
NX = 500
#座標点配列の生成
x = np.linspace(x_min, x_max, NX)
plt.title( u"無限に深い量子井戸の波動関数", fontsize=20, fontname="Yu Gothic", fontweight=1000)
plt.xlabel(r"$x\, [{\rm nm}]$", fontsize=30)
plt.ylabel(r"$ {\rm Enegry}\, [{\rm eV}]$", fontsize=30)
#アニメーション作成用
ims = []
#各時刻における波動関数の計算
for tn in range(ts, te):
#実時間の取得
t = dt * tn
#各コマを描画
for n in range( NS + 1 ):
#波動関数の計算
y = 0.5 * phi(n, x, t).real / (np.sqrt(2.0 / L)) + Energy(n) / eV
#波動関数の表示
if( n == 0 ): img = plt.plot( x/nm, y, colors[n], linestyle='solid', linewidth = 5 )
else: img += plt.plot( x/nm, y, colors[n], linestyle='solid', linewidth = 5 )
#アニメーションに追加
ims.append( img )
#罫線の描画
plt.grid(which = "major", axis = "x", alpha = 0.8, linestyle = "-", linewidth = 1)
plt.grid(which = "major", axis = "y", alpha = 0.8, linestyle = "-", linewidth = 1)
#描画範囲を設定
plt.xlim([-0.6, 0.6])
plt.ylim([-0, 11])
#井戸の概形
plt.vlines([-0.5], -1, 20, "black", linestyles='solid', linewidth = 10 )
plt.vlines([0.5], -1, 20, "black", linestyles='solid', linewidth = 10 )
plt.hlines([0], -0.5, 0.5, "black", linestyles='solid', linewidth = 10 )
#E_0~E_4の表示
for n in range( NS + 1 ):
#式の表示
plt.text(0.62, Energy(n)/eV - 0.20, r"$E_" + str(n) + "$", fontsize = 30)
#エネルギー準位の表示
plt.hlines([Energy(n)/eV], -1, 2, colors[n], linestyles='dashed', linewidth = 2 )
#余白の調整
plt.subplots_adjust(left = 0.12, right = 0.92, bottom = 0.15, top = 0.95)
#アニメーションの生成
ani = animation.ArtistAnimation(fig, ims, interval=10)
#アニメーションの保存
ani.save("output.html", writer=animation.HTMLWriter())
#ni.save('anim.gif', writer='pillow')
#ani.save("output.mp4", writer="ffmpeg", dpi=300)
#グラフの表示
#plt.show()