⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tfqmr.f

📁 网络带宽测试工具
💻 F
字号:
      Subroutine tfqmr( n, nel, m, indx, rowp, matvals, q, x, b, gamma,     &                  maxit, tol, exnrm, prec )! ----------------------------------------------------------------------! --- tfqmr does an iterative solve of Ax = b, where A is in CRS format:!     Integer  indx(nel),!     Integer  rowp(n+1), and!     Real(l_) matvals(nel). !     Real(l_) b(n)       : The righthand side.!     Real(l_) x(n)       : On input the initial guess of the solution!                           On convergence 'x' contains the solution.!     Real(l_) q(n)       : Contains a (left) preconditioning vector.!     Real(l_) gamma(m+1) : Polynomial coefficients used in the!                           preconditioning.!     Integer  maxit      : The maximum number of iterations allowed.! --- Real(l_) tol        : Tolerance used as a stop criterium.!     External prec       : Name of subroutine performing the!                           preconditioning.! ----------------------------------------------------------------------      Use         numerics      Use         floptime      Implicit    None      Integer  :: n, nel, m, maxit      Integer  :: indx(nel), rowp(n+1)      Real(l_) :: matvals(nel)      Real(l_) :: q(n), x(n), b(n)      Real(l_) :: gamma(m+1), tol, exnrm      External    prec      Integer  :: i, im, im0, iter      Real(l_) :: alpha, beta, c, eta, eta0, kappa, rho, rho0, rhstp,     &            sigma, tau, tau0, theta, theta0      Real(l_) :: d(n), g(n), h(n), p(n), r(n), rt(n), v(n), w(n),     &            y(n), y0(n), z(n)      Real(l_) :: dotpr, nrm2      External    dotpr, nrm2! ----------------------------------------------------------------------      Call spmxv( n, nel, indx, rowp, matvals, x, w )      z = b - w      Call prec( n, nel, m, indx, rowp, matvals, z, r, gamma )      w = r      y = r      Call spmxv( n, nel, indx, rowp, matvals, y, z )      Call prec( n, nel, m, indx, rowp, matvals, z, g, gamma )      v = g      d = 0.0_l_      tau = Sqrt( nrm2( n, r ) )      theta = 0.0_l_      eta   = 0.0_l_      rt    = r!! --- We can use 'nrm2' instead of dotpr because rt = r.!      rho = nrm2( n, r )      rhstp = tol*Sqrt( nrm2( n, b ) )      im0 = 1      Do i = 1, maxit         iter = i         sigma = dotpr( n, rt, v )         If ( sigma == 0.0_l_ ) Then            Print *, 'Stop: sigma = 0'; Stop         End If         alpha = rho/sigma         y0 = y         y  = y - alpha*v         Call spmxv( n, nel, indx, rowp, matvals, y, z )         Call prec( n, nel, m, indx, rowp, matvals, z, h, gamma )         Do im = im0, im0 + 1            w = w - alpha*g            theta0 = theta            tau0   = tau            If ( tau0 == 0.0_l_ ) Then               Print *, 'Stop: tau0 = 0'; Stop            End If            theta = Sqrt( nrm2( n, w ) )/tau            c = 1.0_l_/Sqrt( 1.0_l_ + theta*theta )            tau  = tau0*theta*c            eta0 = eta            eta  = c*c*alpha            If ( alpha == 0.0_l_ ) Then               Print *, 'Stop: alpha = 0'; Stop            End If            d = y0 + (theta0*theta0*eta0/alpha)*d            x = x + eta*d            exnrm = Sqrt( nrm2( n, r ) )            kappa = Sqrt( Real( im + 1, l_ ) )*tau            If ( kappa < tol ) Then               Call spmxv( n, nel, indx, rowp, matvals, x, p )               z = b - p               Call prec( n, nel, m, indx, rowp, matvals, z, r, gamma )               exnrm = Sqrt( nrm2( n, r ) )               If ( exnrm < rhstp ) Go To 10  ! <--- Convergence.               flops = flops + n + 9            End If            y0 = y            g  = h         End Do                               ! <--- im-loop         rho0 = rho         rho  = dotpr( n, rt, w )         If ( rho0 == 0.0_l_ ) Then            Print *, 'Stop: rho0 = 0'; Stop         End If         beta = rho/rho0         y = w + beta*y0         Call spmxv( n, nel, indx, rowp, matvals, y, z )         Call prec( n, nel, m, indx, rowp, matvals, z, g, gamma )         v = g + beta*( h + beta*v )         im0 = im0 + 2      End Do                                 ! <--- i-loop! ----------------------------------------------------------------------! --- Normally we would end up here and with no convergence issue a!     warning. Because we only want to see the residual value and!     the speed for benchmarking purposes, we comment out the following!     lines:!!     If ( iter >= maxit ) Then!          iter = maxit!          Print *, 'No convergence in ', maxit, ' iterations;'!          Print *, 'Norm of residual =', exnrm!          Stop!     End If   10 flops = flops + n + 10 + iter*( 22*n + 79 ) ! <--- # of flops.! ----------------------------------------------------------------------      End Subroutine tfqmr

⌨️ 快捷键说明

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