ALPS 2 Tutorials:ED-05 ED Phase Transition/ja

From ALPS
Jump to: navigation, search



次近接相互作用を持つハイゼンベルグ鎖の臨界点

このチュートリアルでは、ハイゼンベルグ鎖について(前回:ED-04)の補足をおこないます。ハミルトニアンに次近接相互作用J_1 \sum_{\langle \langle i,j \rangle \rangle} S_i \cdot S_jを加えてみましょう。


J_2 = 0の極限でこのモデルは普通のハイゼンベルグ鎖に帰着します。これはBethe 仮設を用いて解くことができ、基底状態は臨界的となります。また、 J_2/J_1=0.5というパラメータも可解系となります([1][2])。 この点における基底状態(のひとつ)は、例えば6サイト系で
|\Psi\rangle = \left(|\uparrow\rangle_1 |\downarrow\rangle_2 - |\downarrow\rangle_1 |\uparrow\rangle_2\right) (|\uparrow\rangle_3 |\downarrow\rangle_4 - |\downarrow\rangle_3 |\uparrow\rangle_4) (|\uparrow\rangle_5 |\downarrow\rangle_6 - |\downarrow\rangle_5 |\uparrow\rangle_6)となり、有限のエネルギーギャップを持ちます。


これらのことは、J_1/J_2 \in (0,1/2)での相転移の存在を示しています。(http://pre.aps.org/pdf/PRE/v76/i6/e061108を参照してください。)


このチュートリアルではまずはじめに、スペクトル(特に異なる対称性間のギャップ)が次近接相互作用を調整することによってどのように変化するかを見ることで臨界点を特定します。 次に、臨界鎖のCFTを取り上げます。解析的には、転移点直上でこのモデルはハイゼンベルグ鎖と同じCFTによって記述されます。 しかし、数値計算上の観点からは、対数補正を導く、マージナルな演算子の重みはハイゼンベルグ鎖とは対照に0になるため、スケーリング次元はより正確に見積もれます。


そこで、エネルギーを計算し、一重項励起(S_z = 0)、三重項励起 (S_z=1)を図示してみましょう。


Pythonでの実行

必要なモジュールをインポートします。


import pyalps
import pyalps.pyplot
from pyalps.dict_intersect import dict_intersect
import numpy as np
import matplotlib.pyplot as plt
import copy
import math


S_zを保存量と指定し、そのうちのS_z=0,1でシミュレーションをおこないます。小さいサイズでもレベルクロスが見られるので、系のサイズはL=6,8で十分です。


prefix = 'alps-nnn-heisenberg'
parms = []
for L in [6,8]:
    for Szt in [0,1]:
      for J1 in np.linspace(0,0.5,6):
          parms.append({
              'LATTICE'              : "nnn chain lattice",
              'MODEL'                : "spin",
              'local_S'              : 0.5,
              'J'                    : 1,
              'NUMBER_EIGENVALUES'   : 2,
              'CONSERVED_QUANTUMNUMBER' : 'Sz',
              'Sz_total'             : Szt,
              'J1'                   : J1,
              'L'                    : L
          })

input_file = pyalps.writeInputFiles(prefix,parms)
res = pyalps.runApplication('sparsediag', input_file)
# res = pyalps.runApplication('sparsediag', input_file, MPI=4)
data = pyalps.loadEigenstateMeasurements(pyalps.getResultFiles(prefix=prefix))


今回のデータ解析は以前のチュートリアルのものより少し複雑です。特に、データセットの階層性を強く利用しています。 物理を理解するためには、基底状態と第一励起状態のみ見れば十分でしょう。もしギャップの計算がわかりづらいと思ったならば、あまり考えすぎないでください。


最初に、与えられたパラメータ、つまりJ1、L、Sz_totalのセットに対して計算したエネルギーを集めてソートします。 まず、パラメータ J1,L,Sz_totalを用いてグループ化します。 groupedを走るループで、各要素groupは、異なる運動量に対するデータを集めたリストを持つことになります。これをひとつにまとめます。 また、dict_intersect 関数を使って、まとめたデータセットのprop を得ます。 dict_intersectは辞書のリストを受け取り、和集合を返します。 また、NumPyargsort 関数を用いて、リストy がソートされるようなインデックスのリストを得ます。 これを使うことで、xy と同様にソートすることができます。



grouped = pyalps.groupSets(pyalps.flatten(data), ['J1', 'L', 'Sz_total'])
nd = []
for group in grouped:
    ally = []
    allx = []
    for q in group:
        ally += list(q.y)
        allx += list(q.x)
    r = pyalps.DataSet()
    sel = np.argsort(ally)
    r.y = np.array(ally)[sel]
    r.x = np.array(allx)[sel]
    r.props = dict_intersect([q.props for q in group])
    nd.append( r )
data = nd



次に、S_z=0の状態を含むデータセットから、S_z=1のデータセットに現れるデータを取り出す必要があります。
(訳注:今回のモデルでは、スピンの回転対称性があるため、全スピンや運動量が等しくで全スピンのz成分S_z のみが異なる2S+1 個の状態は 縮退している。 逆に言えば、S_z=m の部分空間で得られたスペクトルは、S \ge m の全てのエネルギースペクトルを(縮退度を抜きにして)含むこととなる。 そのため、下記の操作を行うことで、全スピンがゼロである状態の集合s0と非ゼロである状態の集合s1とに分けることができる。)
これには、subtract_spectrum関数を使用します。 この関数では、第一引数で与えられたデータセットから、第二引数で与えられたデータセットに含まれるデータが削除されます。 オプション引数として、実数の同値判定における許容範囲(相対誤差)を渡せます。


grouped = pyalps.groupSets(pyalps.flatten(data), ['J1', 'L'])
nd = []
for group in grouped:
    if group[0].props['Sz_total'] == 0:
        s0 = group[0]
        s1 = group[1]
    else:
        s0 = group[1]
        s1 = group[0]
    s0 = pyalps.subtract_spectrum(s0, s1)
    nd.append(s0)
    nd.append(s1)
data = nd


基底状態('gs’)と第一励起状態('fe')のエネルギーのみを含むデータセットのリストsector_E を生成します。データセットの持つ辞書propswhich</tth> というキーで基底状態’gs’ か励起状態 ‘fe’ を追加することで、状態を区別します。この情報を元に、<tt>collectXY関数を用いて、gs, fe それぞれのエネルギーの次近接相互作用依存性の図を生成することができます。


sector_E = []
grouped = pyalps.groupSets(pyalps.flatten(data), ['Sz_total', 'J1', 'L'])
for group in grouped:
    allE = []
    for q in group:
        allE += list(q.y)
    allE = np.sort(allE)
   
    d = pyalps.DataSet()
    d.props = dict_intersect([q.props for q in group])
    d.x = np.array([0])
    d.y = np.array([allE[0]])
    d.props['which'] = 'gs'
    sector_E.append(d)
   
    d2 = copy.deepcopy(d)
    d2.y = np.array([allE[1]])
    d2.props['which'] = 'fe'
    sector_E.append(d2)

sector_energies = pyalps.collectXY(sector_E, 'J1', 'Energy', ['Sz_total', 'which', 'L'])
plt.figure()
pyalps.pyplot.plot(sector_energies)
plt.xlabel('$J_1/J$')
plt.ylabel('$E_0$')
plt.legend(prop={'size':8})


最後に、一重項、三重項ギャップの計算をおこないます。それぞれ、(a)一重項状態(S_z=0)の第一励起状態、(b)三重項(S_z=1)の基底状態、と一重項状態の基底状態とのエネルギー差で定義されます。

grouped = pyalps.groupSets( pyalps.groupSets(pyalps.flatten(data), ['J1', 'L']), ['Sz_total'])

gaps = []
for J1g in grouped:
    totalmin = 1000
    for q in flatten(J1g):
        totalmin = min(totalmin, np.min(q.y))
   
    for Szg in J1g:
        allE = []
        for q in Szg:
            allE += list(q.y)
        allE = np.sort(allE)
        d = pyalps.DataSet()
        d.props = pyalps.dict_intersect([q.props for q in Szg])
        d.props['observable'] = 'gap'
        print totalmin,d.props['Sz_total']
        if d.props['Sz_total'] == 0:
            d.y = np.array([allE[1]-totalmin])
        else:
            d.y = np.array([allE[0]-totalmin])
        d.x = np.array([0])
        d.props['line'] = '.-'
        gaps.append(d)

gaps = pyalps.collectXY(gaps, 'J1', 'gap', ['Sz_total', 'L'])

plt.figure()
pyalps.pyplot.plot(gaps)
plt.xlabel('$J_1/J$')
plt.ylabel('$\Delta$')
plt.legend(prop={'size':8})

plt.show()


VisTrails、コマンドラインでの実行

VisTrails の実行ファイルはed-05-nnn-chain.vtです。コマンドライン実行用のパラメータファイルはparm_nnn-ptです。


第2近接結合を持つハイゼンベルグ鎖: CFT assignments

前回のチュートリアルで扱った、最近接相互作用のみの、一様な反強磁性ハイゼンベルグ鎖では系のサイズに対する対数補正が現れますが、 J1-J2 フラストレート鎖の臨界点ではこの対数補正が劇的に小さくなります。 相互作用のパターンが異なるにもかかわらず、連続極限においてこの2つのモデルは同じ場の理論で表わせるので、J1-J2 フラストレート鎖の臨界点からハイゼンベルグ鎖のスケーリング次元を得ることができます。より詳細な議論は、I Affleck et al 1989 J. Phys. A: Math. Gen. 22 511を参照してください。



2つのモデルでの、スペクトルの計算結果を比較してみてください。 今回のモデルのほうが収束が早く、スケーリング次元を見つけるのが容易だとわかるかと思います。

Pythonでの実行

次の手順に計算を開始します。


parms_ = {
    'LATTICE'              : "nnn chain lattice",
    'MODEL'                : "spin",
    'local_S'              : 0.5,
    'J'                    : 1,
    'J1'                   : 0.25,
    'NUMBER_EIGENVALUES'   : 5,
    'CONSERVED_QUANTUMNUMBER' : 'Sz',
    'Sz_total' : 0
}
prefix = 'nnn-heisenberg'
parms = []
for L in [10,12]:
    parms_.update({'L':L})
    parms.append(copy.deepcopy(parms_))



スクリプトの他の部分はED-04のものと同じです。[3]を参照してください。


VisTrails,コマンドラインでの実行

VisTrails用のファイルはed-05-nnn-chain.vt です。コマンドライン実行用のパラメータファイルはparm_nnn-heisenberg です。