trlcore.f90

来自「用于计算矩阵的特征值,及矩阵的其他运算.可以用与稀疏矩阵」· F90 代码 · 共 1,933 行 · 第 1/5 页

F90
1,933
字号
          title = 'Ritz values saved (may not be ordered)..'       End If       Call trl_print_real(info, title, alpha(1:kept+locked))       title = 'Residual norms of the saved Ritz pairs..'       betrot(1:kept+locked) = Abs(beta(1:kept+locked))       Call trl_print_real(info, title, betrot(1:kept+locked))    End If    If (info%verbose .Gt. 7) Then       Do j1 = 1, Min(kept, info%verbose)          Do j2 = 1, j1             wrk2(j2) = Dot_product(yy(j2*jml-jml+1:j2*jml),&                  & yy(j1*jml-jml+1:j1*jml))          End Do          wrk2(j1) = wrk2(j1) - 1          Write(title, *) 'Orthogonality level of y(', j1, ') ..'          Call trl_print_real(info, title, wrk2(1:j1))       End Do    End If    If (info%verbose .Gt. 10) Then       Do j1 = 1, Min(kept, info%verbose)          Write(title,*) 'eigenvector ', j1, ' of Q''AQ..'          Call trl_print_real(info, title, yy((j1-1)*jml+1:j1*jml))       End Do    End If    If (info%verbose .Gt. 10) Then       j1n = Min(nrow, info%verbose)       Do j1 = 1, Min(kept+locked, mev)          Write(title,*) 'Ritz vector ', j1, ' (1:', j1n, ') ..'          Call trl_print_real(info, title, evec(1:j1n,j1))       End Do    End If  End Subroutine print_restart_state  ! print the final state  Subroutine print_final_state    Interface       ! print real array for debugging       Subroutine trl_print_real(info, title, array)         Use trl_info         Implicit None         Type(TRL_INFO_T), Intent(in) :: info         Character(*), Intent(in) :: title         Real(8), Dimension(:), Intent(in) :: array       End Subroutine trl_print_real    End Interface    title = 'Final eigenvalues  (in ascending order)..'    Call trl_print_real(info, title, eval(1:kept))    If (info%verbose .Gt. 4) Then       title = 'Final residual norms..'       Call trl_print_real(info, title, beta(1:kept))    End If    If (info%verbose .Gt. 8) Then       Do j1 = 1, Min(kept, info%verbose)          Write(title,*) 'Eigenvector ', j1, ' of Q''AQ ..'          Call trl_print_real(info, title, yy((j1-1)*jml+1:j1*jml))       End Do    End If    If (info%verbose .Gt. 10) Then       j1n = Min(nrow, info%verbose)       Do j1 = 1, Min(kept, mev)          Write(title,*) 'Ritz vector ', j1, ' (1:', j1n, ') ..'          Call trl_print_real(info, title, evec(1:j1n,j1))       End Do    End If  End Subroutine print_final_state  ! do check pointing  Subroutine write_checkpoint    Interface       ! write the checkpoint files       Subroutine trl_write_checkpoint(cp_io, filename, nrow, alpha,&            & beta, evec, lde, me, base, ldb, nb, ierr)         Implicit None         Character(*), Intent(in) :: filename         Integer, Intent(in) :: cp_io, nrow, ldb, lde, me, nb         Real(8), Intent(in) :: alpha(me+nb-1), beta(me+nb-1)         Real(8), Intent(in) :: evec(lde,me), base(ldb,nb)         Integer, Intent(out) :: ierr       End Subroutine trl_write_checkpoint       ! find the minimum of the flag on all PEs       Function trl_sync_flag(mpicom, inflag) Result(outflag)         Implicit None         Integer :: outflag         Integer, Intent(in) :: mpicom, inflag       End Function trl_sync_flag       Function trl_pe_filename(base, my_rank, npe) Result(filename)         Implicit None         Integer, Intent(in) :: my_rank, npe         Character(*), Intent(in) :: base         Character(132) :: filename       End Function trl_pe_filename    End Interface    Integer :: ii, c1, c2    title = trl_pe_filename(info%cpfile, info%my_pe, info%npes)    Call System_clock(c1)    Call trl_write_checkpoint(info%cpio, title, nrow, alpha,&         & beta, evec, lde, j1n, base, ldb, j2n, ii)    Call System_clock(c2)    If (c2.Gt.c1) Then       info%clk_out = info%clk_out + (c2 - c1)    Else       info%clk_out = info%clk_out + ((info%clk_max-c1)+c2)    End If    info%wrds_out = info%wrds_out + jnd*(nrow+nrow+2) + nrow + 2    info%stat = trl_sync_flag(info%mpicom, ii)  End Subroutine write_checkpoint  ! dump important variables when return due to error  Subroutine log_error_state    Interface       ! print real array for debugging       Subroutine trl_print_real(info, title, array)         Use trl_info         Type(TRL_INFO_T), Intent(in) :: info         Character(*), Intent(in) :: title         Real(8), Dimension(:), Intent(in) :: array       End Subroutine trl_print_real       ! print integer array for debugging       Subroutine trl_print_int(info, title, array)         Use trl_info         Type(TRL_INFO_T), Intent(in) :: info         Character(*), Intent(in) :: title         Integer, Dimension(:), Intent(in) :: array       End Subroutine trl_print_int       ! print a time stamp       Subroutine trl_time_stamp(iou)         Implicit None         Integer, Intent(in) :: iou       End Subroutine trl_time_stamp       ! a short of the print info function that can be called by       ! indivadual PE       Subroutine trl_terse_info(info, iou)         Use trl_info         Implicit None         Type(TRL_INFO_T), Intent(in) :: info         Integer, Intent(in) :: iou       End Subroutine trl_terse_info    End Interface    Call trl_time_stamp(info%log_io)    title = 'Dumping the content of the variables on error..'    iwrk(1) = info%stat    Call trl_print_int(info, title, iwrk(1:1))    i2 = info%log_io    Call trl_terse_info(info, i2)    Write (i2,*) 'This Lanczos iteration started With ', kept,&         & ' vectors.'    Write (i2,*) 'There are ', jnd, '(', j1, ', ', j2,&         & ') Lanczos vectors currently.'    If (jnd .Ne. j1+j2) jnd = j1 + j2    If (jnd.Lt.0 .Or. jnd.Gt.info%klan) jnd = 0    title = 'Content of eval ..'    Call trl_print_real(info, title, eval)    If (jnd .Gt. 0) Then       Write (title, *) 'Alpha(1:', jnd, ') .. '       Call trl_print_real(info, title, alpha(1:jnd))       title(1:5) = ' Beta'       Call trl_print_real(info, title, beta(1:jnd))       Write (title, *) 'Alfrot(1:', jnd, ') .. '       Call trl_print_real(info, title, alfrot(1:jnd))       title(1:3) = 'bet'       Call trl_print_real(info, title, betrot(1:jnd))    End If    If (j1 .Gt. 0) Then       title = 'the First row of evec ..'       Call trl_print_real(info, title, evec(1, 1:j1))       Write (title, *) 'row ', nrow, ' of evec ..'       Call trl_print_real(info, title, evec(nrow, 1:j1))    End If    If (j2 .Gt. 0) Then       title = 'the First row of base ..'       Call trl_print_real(info, title, base(1,1:j2))       Write (title, *) 'row ', nrow, ' of base ..'       Call trl_print_real(info, title, base(nrow,1:j2))    End If    If (Associated(qb)) Then       Write (title, *) 'Content of qb (q_', jnd-1, ') ..'       Call trl_print_real(info, title, qb)    End If    If (Associated(qa)) Then       Write (title, *) 'Content of qa (q_', jnd, ') ..'       Call trl_print_real(info, title, qa)    End If    If (Associated(rr)) Then       Write (title, *) 'Content of rr (residual == q_', jnd+1, ') ..'       Call trl_print_real(info, title, rr)    End If    If (info%my_pe.Eq.0 .And. info%log_io.Ne.6) Then       Write (*, *) 'TRLanczos returned with error ', info%stat       If (info%verbose .Gt. 0) Then          Write (*, *) 'Contents of most variables are dumped to ',&               & 'log file ', Trim(info%log_file)       Else          Write (*, *) 'Contents of most variables are dumped to ',&               &'IO unit # ', info%log_io       End If    End If  End Subroutine log_error_stateEnd Subroutine trlanczos!!!! check to make sure the initial guess vector contains valid nonzero! numbers if not fill with random numbers! this routine will also read the checkpoint files to restore the! previous state of the Lancozs iterations!!!Subroutine trl_initial_guess(nrow, evec, lde, mev, base, ldb, nbas,&     & alpha, beta, j1, j2, info, wrk, lwrk)  Use trl_info  Implicit None  Type(TRL_INFO_T) :: info  Integer, Intent(in) :: nrow, lde, ldb, mev, nbas, lwrk  Integer, Intent(out) :: j1, j2  Real(8) :: wrk(lwrk), base(ldb,nbas), evec(lde,mev)  Real(8) :: alpha(mev+nbas-1), beta(mev+nbas-1)  Interface     ! read the checkpointfile     Subroutine trl_read_checkpoint(cp_io, filename, nrow, evec, lde,&          & mev, j1, base, ldb, nbas, j2, alpha, beta, ierr)       Implicit None       Character(*), Intent(in) :: filename       Integer, Intent(in) :: cp_io, nrow, lde, mev, ldb, nbas       Integer, Intent(out) :: j1, j2, ierr       Real(8), Intent(out) :: alpha(mev+nbas-1), beta(mev+nbas-1)       Real(8), Intent(out) :: base(ldb,nbas), evec(lde,mev)     End Subroutine trl_read_checkpoint     ! the orthogonalization routine -- Classical Gram-Schmidt     Subroutine trl_cgs(mpicom, myid, nrow, v1, ld1, m1, v2, ld2,&          & m2, rr, rnrm, alpha, north, nrand, wrk, ierr)       Integer, Intent(inout) :: north, nrand, ierr       Integer, Intent(in) :: mpicom, myid, nrow, ld1, ld2, m1, m2       Real(8), Intent(inout) :: rnrm, alpha       Real(8), Intent(in) :: v1(ld1,m1), v2(ld2*m2)       Real(8), Intent(inout) :: rr(nrow), wrk(m1+m2+m1+m2)     End Subroutine trl_cgs     ! generate filenames for each PE     Function trl_pe_filename(base, my_rank, npe) Result(filename)       Implicit None       Integer, Intent(in) :: my_rank, npe       Character(*), Intent(in) :: base       Character(132) :: filename     End Function trl_pe_filename     ! find the minimum of the flag on all PEs     Function trl_sync_flag(mpicom, inflag) Result(outflag)       Implicit None       Integer :: outflag       Integer, Intent(in) :: mpicom, inflag     End Function trl_sync_flag     Subroutine trl_g_sum(mpicom, n, xx, wrk)       Implicit None       Integer, Intent(in) :: mpicom, n       Real(8), Intent(out) :: wrk(n)       Real(8), Intent(inout) :: xx(n)     End Subroutine trl_g_sum     Subroutine trl_check_orth(info, nrow, v1, ld1, j1, v2, ld2, j2, wrk, lwrk)       Use trl_info       Implicit None       Integer, Intent(in) :: nrow, ld1, ld2, j1, j2, lwrk       Type(TRL_INFO_T), Intent(in) :: info       Real(8), Intent(in) :: v1(ld1,j1), v2(ld2,j2)       Real(8) :: wrk(lwrk)     End Subroutine trl_check_orth  End Interface  !  ! local variable  !  Integer :: i, ii, j, nran, north  Real(8) :: tmp, rnrm  Character(132) :: file  Integer, Dimension(:), Allocatable :: rseed  !  ! generate random seeds based on current clock ticks  Call Random_seed(SIZE=ii)    ! find out the size of seed  Allocate(rseed(ii))  Call Random_seed(GET=rseed)  ! get the current seeds  i = Mod(info%my_pe, ii) + 1  j = Max(Maxval(rseed), info%nloc)  Call System_clock(rseed(i))  ! get the current clock ticks  ! just in case the clocks are absolutely synchronized  If (info%my_pe .Gt. 0) Then     rseed(i) = rseed(i) - Sign(Int(info%my_pe*Sqrt(Dble(j))), rseed(i))  End If  Call Random_seed(PUT=rseed)  ! initialize the random number generator  Deallocate(rseed)  !  j = info%nec+1  If (info%guess .Gt. 1) Then     ! retrieve a check-point file     i = info%cpio     If (info%oldcpf .Ne. '') Then        file = trl_pe_filename(info%oldcpf, info%my_pe, info%npes)     Else        file = trl_pe_filename(info%cpfile, info%my_pe, info%npes)     End If     Call System_clock(ii)     Call trl_read_checkpoint(info%cpio, file, nrow, evec(1,j), lde,&          & mev-info%nec, j1, base, ldb, nbas, j2, alpha(j), beta(j),&          & i)     info%stat = trl_sync_flag(info%mpicom, i)     Call System_clock(i)     If (i.Gt.ii) Then        info%clk_in = i - ii     Else        info%clk_in = (info%clk_max - ii) + i     End If     info%wrds_in = (j1+j2)*(nrow+nrow+2) + nrow + 2     j1 = j1 + info%nec     If (info%stat .Ne. 0) Return  Else     If (info%guess .Le. 0) Then        ! generate an arbitrary initial starting vector        ! if (info%guess == 0), use the vector [1, 1, ...]^T        ! else perturb some random locations of the above vector        evec(1:nrow,j) = 1.0D0        nran = Min(1-info%guess, lwrk)        nran = 2*(nran/2)        If (nran.Gt.0 .And. nran.Lt.nrow) Then           Call Random_number(wrk(1:nran))           Do i = 1, nran-1, 2              ii = Int(nrow*wrk(i))+1              evec(ii,j) = evec(ii,j) + wrk(i+1) - 0.5D0           End Do           info%flop = info%flop + nran + nran        Else If (nran .Ge. nrow) Then           Call random_vector        End If     End If     j1 = info%nec     j2 = 0  End If  tmp = 0.0  ! make sure the norm of the next vector can be computed  wrk(1) = Dot_product(evec(1:nrow,j), evec(1:nrow,j))  Call trl_g_sum(info%mpicom, 1, wrk(1), wrk(2))  info%flop = info%flop + nrow+nrow  If (wrk(1).Ge.Tiny(tmp) .And. wrk(1).Le.Huge(tmp)) Then     ! set rnrm to let trl_CGS normalize evec(1:nrow, j)     rnrm = Sqrt(wrk(1))  Else     Call random_vector  End If  !  ! orthogonalize initial guess against all existing vectors  !  i = 0  tmp = 1.0D0  nran = info%nrand  north = info%north  If (j1 .Lt. mev) Then     Call trl_cgs(info%mpicom, info%my_pe, nrow, evec, lde, j1,&          & base, ldb, 0, evec(1,j1+1), rnrm, tmp, i,&          & info%nrand, wrk, info%stat)  Else If (j2 .Le. 0) Then     Call trl_cgs(info%mpicom, info%my_pe, nrow, evec, lde, j1,&          & evec, lde, 0, base, rnrm, tmp, i, info%nrand, wrk,&          & info%stat)  Else     Call trl_cgs(info%mpicom, info%my_pe, nrow, evec, lde, j1,&          & base, ldb, j2, base(1,j2+1), rnrm, tmp, i, info%nrand,&          & wrk, info%stat)  End If  info%flop = info%flop + 4*nrow*((info%north-north)*(j1+j2) + &       & info%nrand-nran) + nrow  If (info%verbose.Gt.6) Then     If (j1 .Lt. mev) Then        i = j1 + 1        ii = j2     Else        i = j1        ii = j2 + 1     End If     Call trl_check_orth(info, nrow, evec, lde, j1, base, ldb, ii, wrk,&          & lwrk)  End If  ReturnContains  ! an internal subroutine to generate random vector  Subroutine random_vector    Call Random_number(evec(1:nrow, j))    evec(1:nrow, info%nec+1) = evec(1:nrow, info%nec+1) +&         & evec(1:nrow, info%nec+1) +&         & Cshift(evec(1:nrow, info%nec+1), 1) +&         & Cshift(evec(1:nrow, info%nec+1), -1)    info%nrand = info%nrand + 1    info%flop = info%flop + 4*nrow  End Subroutine random_vectorEnd Subroutine trl_initial_guess!!!! full re-orthogonalization for TRLANCZOS!!\Algorithm!

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?