CTMRG for 2D Ising Model
@
c123456789012345678901234567890123456789012345678901234567890123456789012 c ----- ----- c ----- Vertex CTMRG for Ising model: Tutorial for ----- c ----- MC Students. ----- c ----- ----- c ----- '2005/04/29, Ver.0.1 by T.Nishino ----- c ----- ----- module var_size integer,parameter :: mIT = 10000 ! Maximum Iteration Number integer,parameter :: iq = 2 ! Ising (2-state) spins integer,parameter :: mXX = 40 ! Maximum value of 'm' integer,parameter :: mBW = iq**4 ! Size of the Boltzmann Weight integer,parameter :: mXT = iq**3 & *mXX**2 ! Variable Size end module c program main; use var_size integer L, LL ! System Size L, Max. System Size LL integer m, mX ! Block Spin State m, Max. Block Spin State mX integer mN ! The value of m in the NeXT iteration. integer tp ! Temporary Variable c real(8) K ! Inverse Temperature 1/T real(8) eps ! Decouple element (***) real(8) mg ! Spontaneous Magnetization real(8) u ! Bond Energy real(8) Z ! Normalized Partition Function real(8) eP, fP ! Normalization Const. for HRTM real(8) eC, fC ! Normalization Const. for CTM real(8) F(0:mIT) ! Free Energy c real(8) W(0:mBW) ! Boltzmann Weight real(8) S(0:mBW) ! Ising Spin Weight real(8) Y(0:mBW) ! Decouple Weight (***) real(8) C(0:mXT) ! Corner Transfer Matrix real(8) D(0:mXT) ! Corner Decouple Matrix (***) real(8) P(0:mXT) ! Half Row Transfer Matrix real(8) H(0:mXT) ! Half Row Decouple Matrix (***) real(8) G1(0:mXT) ! Work Area real(8) G2(0:mXT) ! Work Area real(8) G3(0:mXT) ! Work Area real(8) G4(0:mXT) ! Work Area c call getprm( L, mX, K, eps ) ! Set Physical Parameters call initbw( K, W, S ) ! Initialize Boltzmann Weights c ! Set CTM, HRTM, etc. LL = 2; eC = 0.0d0; C(0)= 1.0d0 m = 1; eP = 0.0d0; P(0)= 1.0d0; P(1)= 1.001d0 goto 20 c 10 continue call rjoint( m, m, iq *m, C, P, G1 ) call rjoint( m*iq, m, iq *m, P, G1, G2 ) call rjoint( m, m, iq**2*m, C, G2, G3 ) call jointX( iq, m, G3, G2, C ) call symchW( iq, G2, C ) c call observ( mg, Z, W, S, G2 ) c call extP( iq, m, W, P, G2 ) call extC( iq, m, G1, G2, G3 ) call sjoint( iq *m, iq*m, G3, C ) call sjoint( iq *m, iq*m, C, G1 ) call trace( iq *m, G1, Z ) c call diag( iq*m, G1, C, P ) ! C/P_temp mN = min( iq*m, mX ) tp = iq*m*(iq*m-mN ) call renoP( iq,iq*m, mN, G2, P, G1(tp) ) call renoC( iq*m, mN, G3, C, G1(tp) ); m = mN F(LL)= eP*8 + eC*4 + log(Z) c if(LL.gt.8) then; write(6,100) LL,mg,(F(LL)+F(LL-4)-2*F(LL-2))/8 else; write(6,100) LL,mg,0.0d0 end if 100 format('#',I4, F16.10, F16.10 ) c 20 continue call symchP( iq, m, P, G1 ) ! Check the Symmetry of HRTM call symchC( m, C, G1 ) ! Check the Symmetry of CTM call norm( iq *m**2, P, fP ) ! Normalize HRTM call norm( m**2, C, fC ) ! Normalize CTM eC= eC + 2*eP + log(fC) ! Normalization Const for CTM eP= eP + log(fP) ! Normalization Const for HRTM LL = LL + 2; if( LL .LT. L ) goto 10 end program main ccccc subroutine errstp( ch ) ; character(8) ch write(6,*) 'errstp <',ch,'>'; stop "Input_Error"; end ccccc subroutine getprm( L, mX, K eps); use var_size integer L, mX; real(8) K, eps write(6,*)'Max. Iteration # L'; read(5,*) L ; if( L.GT.mIT ) & call errstp( 'L > mIT') write(6,*)'Maximum Dim. mX>= m'; read(5,*) mX; if( mX.GT.mXX ) & call errstp( 'mX > mXX') write(6,*)'Parameter K = J/T '; read(5,*) K write(6,*)'Parameter eps '; read(5,*) eps write(6,*)' mX = ', mX,' K = ',K,' eps = ',eps end ccccc subroutine initbw( K, W, S); use var_size integer i, ibt; real(8) Xi, K, W(0:*), S(0:*) c Xi = exp(2*K) + sqrt(exp(2*K)**2-1) do i = 0, iq**4-1 W(i)= Xi**(ibt(i)-2)/2**3 + Xi**(-ibt(i)+2)/2**3 S(i)= Xi**(ibt(i)-2)/2**3 - Xi**(-ibt(i)+2)/2**3 end do end ccccc integer function ibt( D ); integer D ibt = mod(D,2) + mod(D/2,2) + mod(D/4,2) + mod(D/8,2); end cccccc subroutine exchg2( m1, m2, A, B ) integer i, j, m1, m2; real(8) A(0:*), B(0:*) do i = 0, m1-1 do j = 0, m2-1; B(j*m1+i) = A(i*m2+j) end do; end do; end cccccc subroutine exchg3( m1, m2, m3, A, B ) integer i, j, m1, m2, m3; real(8) A(0:*), B(0:*) do i = 0, m1-1 do j = 0, m2-1; B((j*m1+i)*m3:(j*m1+i)*m3 + m3-1) & = A((i*m2+j)*m3:(i*m2+j)*m3 + m3-1) end do; end do; end cccccc subroutine trace( m, A, Tr ) integer i, m; real(8) A(0:*), Tr; Tr = 0.0d0 do i = 0, m-1; Tr = Tr + A(i*m+i) end do; end cccccc subroutine utrace( m1, m2, A, B ) integer i, m1, m2; real(8) A(0:*), B(0:*) B(0:m2-1)= 0.0d0 do i = 0, m1-1; B(0:m2-1)= B(0:m2-1) + A(i*m2:i*m2 + m2-1) end do; end cccccc subroutine sjoint( m1, m2, A, B ) integer i,j, m1, m2; real(8) A(0:*), B(0:*) B(0:m2*m2-1)= 0.0d0 do i = 0, m1-1 do j = 0, m2-1; B(j*m2:j*m2 + m2-1) = ! *m1* m2 & B(j*m2:j*m2 + m2-1) + A(i*m2+j) ! *m1* m2 & * A(i*m2:i*m2 + m2-1) ! * * m2 m2 end do; end do; end cccccc subroutine ujoint( m1, m2, m3, A, B, C ) integer i,j, m1, m2, m3; real(8) A(0:*), B(0:*), C(0:*) C(0:m2*m3-1)= 0.0d0 do i = 0, m1-1 do j = 0, m2-1; C(j*m3:j*m3 + m3-1) = ! *m1* m2 & C(j*m3:j*m3 + m3-1) + A(i*m2+j) ! *m1* m3 & * B(i*m3:i*m3 + m3-1) ! * * m2 m3 end do; end do; end cccccc - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - subroutine rjoint( m1, m2, m3, A, B, C ) integer m1, m2, m3 real(8) A(m2,m1), B(m3,m2), C(m3,m1) C = MATMUL(B,A) end cccccc - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - subroutine jointX( q, m, E, F, tp ) integer q, m; real(8) E(0:*), F(0:*), tp(0:*) c ! iabj +-i-+---+ call exchg2( m *q*q, m, E,tp ) ! jiab | d | call exchg3( m,m, q*q, tp, E ) ! jicd + a c + call ujoint( m*m, q*q, q*q,tp, E, F ) ! abcd | b | end ! +---+-j-+ cccccc subroutine inpro( N, f, A, B ) integer i, N; real(8) f, A(0:*), B(0:*); f=0.0d0 do i = 0, N-1; f = f + A( i ) *B( i ) end do; end cccccc subroutine observ( mg, Z, W, S, G ); use var_size real(8) mg, Z, W(0:*), S(0:*), G(0:*) call inpro( iq**4, Z, W, G ) call inpro( iq**4, mg, S, G ); mg = mg / Z end cccccc subroutine extP( q, m, W, P, G ) integer q, m; real(8) W(0,*), P(0:*), G(0:*) c call exchg2( m, q*m, P, G ) ! iaj -> [a]ji call ujoint( q, m*m, q**3, G, W, P ) ! [a] bcd call exchg2( m,m *q**3, P, G ) ! ibcdj <---- jibcd call exchg3( m, q,m *q**2, G, P ) ! bicdj c ! i b G(0:m**2*q**3-1) = P(0:m**2*q**3-1) ! +-a-+-c end ! j d cccccc subroutine extC( q, m, G1, G2, G3 ) integer q, m; real(8) G1(0:*), G2(0:*), G3(0:*) c call exchg3( m, q, m, G1, G3 ) ! iaj -> [ai]j call ujoint( q*m, m, q**2*m, G3, G2, G1 ) ! [ai] bck call exchg3( m, q, q *m, G1, G3 ) ! bjck <--- jbck end ccccc subroutine extD( q, m, Y, H, D, G ) integer i,j,k,l, q, m; real(8) Y(0:*), H(0:*), D(0:*), G(0:*) c call rjoint( m, m, m, H, D, G ) call rjoint( m, m, m, G, H, D ) c do i = 0, q-1; do j = 0, m-1 do k = 0, q-1; do l = 0, m-1 G(((i*m+j)*q + k)*m+l) = Y(i*q+k)*D(j*m+l) end do; end do; end do; end do D(0:q*q*m*m-1) = G(0:q*q*m*m-1) end ccccc subroutine extH( q, m, Y, H, G ) integer i,j,k,l, q, m; real(8) Y(0:*), H(0:*), G(0:*) c do i = 0, q-1; do j = 0, m-1 do k = 0, q-1; do l = 0, m-1 G(((i*m+j)*q + k)*m+l) = Y(i*q+k)*H(j*m+l) end do; end do; end do; end do H(0:q*q*m*m-1) = G(0:q*q*m*m-1) end ccccc subroutine diag( N, A, E, tp ) integer N, info; real(8) A(0:*), E(0:*), tp(0:*) c call DSYEV('V','U', N, A, N, E, tp, (N+2)*N, info ) c-SX- call dcsmaa( A, N, N, E, tp, info ) if( info .ne. 0 ) then write(6,*) 'dsyev_info = ', info; call errstp(' -diag- ') end if end cccccc subroutine renoP( q, qm, mN, G, P, R ) integer q, qm, mN; real(8) G(0:*), P(0:*), R(0:*) call rjoint( mN, qm, q*qm, R, G, P ) ! x[ai] call exchg3( mN, q, qm, P, G ) ! [ai]bcj -> xbcj call exchg2( q*mN, qm, G, P ) ! bxcj call rjoint( mN, qm, q*mN, R, P, G ) ! y[cj] <- cjbx c ! [cj]bx P(0:q*mN**2-1) = G(0:q*mN**2-1) ! y bx end ccccc subroutine renoC( qm, mN, G, C, R ) integer qm, mN; real(8) G(0:*), C(0:*), R(0:*) call rjoint( mN, qm, qm, R, G, C ) ! x[ai] y[bj] call exchg2( mN, qm, C, G ) ! [ai]bj -> xbj -> [bj]x call rjoint( mN, qm, mN, R, G, C ) ! y x end cccccc subroutine norm( N, V, w ) integer N; real(8) V(0:*), w call maxel( N, V, w ); V(0:N-1)= V(0:N-1)/w end ccccc subroutine maxel( N, V, w ) integer i, N; real(8) V(0:*), w; w = 0.0d0 do i = 0, N-1; if( abs(V(i)) .GT. w ) w = abs(V(i)) end do; end ccccc ccccc -------------------------------------- ccccc ---------- Debug Routines ------------ ccccc -------------------------------------- ccccc subroutine symchP( q, m, P, tp ) integer i,j,k, q, m; real(8) P(0:*), tp(0:*), T, S; S = 0.0d0 do i = 0, m-1 do j = 0, q-1 do k = 0, m-1 ; tp((i*q+j)*m+k) & = ( P((i*q+j)*m+k) + P((k*q+j)*m+i) )/2 if( S .lt. ABS( P((i*q+j)*m+k) - P((k*q+j)*m+i) ) ) & S = ABS( P((i*q+j)*m+k) - P((k*q+j)*m+i) ) end do; end do; end do c P(0:m*q*m-1) = tp(0:m*q*m-1); call maxel( m*q*m, P, T) c if( S/T .gt. 1.0E-12 ) write(6,*) 'sym P = ', S/T, q, m end cccccc subroutine symchC( m, C, tp ) integer i,j, m; real(8) C(0:*), tp(0:*), T, S; S = 0.0d0 do i = 0, m-1 do j = 0, m-1 ; tp(i*m+j) =( C(i*m+j) + C(j*m+i) )/2 if( S .lt. ABS( C(i*m+j) - C(j*m+i) ) ) & S = ABS( C(i*m+j) - C(j*m+i) ) end do; end do c call maxel( m*m, C, T); C(0:m*m-1)= tp(0:m*m-1) c if( S/T .gt. 1.0E-12 ) write(6,*) 'sym C = ', S/T, m end cccccc subroutine symchW( q, W, tp ) integer i,j,k,l, q; real(8) W(0:*), tp(0:*), T, S; S = 0.0d0 do i = 0, q-1 do j = 0, q-1 do k = 0, q-1 do l = 0, q-1 ; tp(((i*q+j)*q+k)*q+l) = & ( W(((i*q+j)*q+k)*q+l)+ W(((j*q+k)*q+l)*q+i) & + W(((k*q+l)*q+i)*q+j)+ W(((l*q+i)*q+j)*q+k) & + W(((i*q+l)*q+k)*q+j)+ W(((l*q+k)*q+j)*q+i) & + W(((k*q+j)*q+i)*q+l)+ W(((j*q+i)*q+l)*q+k) )/8 if( S .lt. ABS( W(((i*q+j)*q+k)*q+l)- W(((j*q+k)*q+l)*q+i) ) ) & S = ABS( W(((i*q+j)*q+k)*q+l)- W(((j*q+k)*q+l)*q+i) ) end do; end do; end do; end do c call maxel( q**4, W, T ); W(0:q**4-1) = tp(0:q**4-1) if( S/T .gt. 1.0E-12 ) & write(6,*) ' sym W = ', S/T, q end