声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

查看: 3587|回复: 4

[Fortran] 求一个用于稀疏矩阵求解的ICCG的fortran程序

[复制链接]
发表于 2007-6-27 16:37 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?我要加入

x
rt,谢谢!
回复
分享到:

使用道具 举报

发表于 2007-7-2 11:19 | 显示全部楼层
发表于 2007-7-5 19:59 | 显示全部楼层

回复 #2 风花雪月 的帖子

打不开啊
发表于 2007-7-23 15:14 | 显示全部楼层
我这里能够正常打开
发表于 2007-7-23 15:14 | 显示全部楼层
  1.       implicit real(a-h,o-z)
  2.       real a(200000),af(200000),b(28000),x(28000),
  3.      $      anrm,xnrm,resd,g(28000),p(28000),t1(28000),t2(28000)
  4.       integer ia(28001),ja(200000),nit(3)
  5.       real d,c2,a2,cf
  6.       common /tomm/ a,af,ia,ja
  7.       common /area2/ d,c2,a2,cf
  8.        common /order/ iorflg
  9.        data nit/1,5,10/
  10. c
  11. c     this is a main program for running the incomplete LU
  12. c     conjugate gradient for solving linear systems.
  13. c     the matrix need not be symmetric.
  14. c
  15. c     ilucg this flag if 1 will cause incomplete factoization
  16. c               if 0 no factorization just straight cg
  17. c
  18. c     write(6,*)' start in main'
  19. c
  20. c     call trapov(100)
  21.       loca = 200000
  22.     1 continue
  23. c     write(6,*) 'input ineum5,ineum6,irot,iorflg'
  24. c     write(6,*)'set irot<0 to stop'
  25. c     read(5,*) ineum5,ineum6,irot,iorflg
  26. c     if( irot .lt. 0 ) then
  27. c       write(6,*)' end test'
  28. c       stop
  29. c     end if
  30. c     write(6,*) 'ineum5,ineum6,irot,iorflg',ineum5,ineum6,irot,iorflg
  31. c     write(6,*)'input mesh cells for x, y, and z'
  32. c     read(5,*)imx,imy,imz
  33. c     write(6,*)'inner, middle, and outer fill-in integers'
  34. c     read(5,*)ifli,iflm,iflo
  35. cc    write(6,*)'ising (normally zero)'
  36. cc    read(5,*)ising
  37.       ineum5 = 1
  38.       ineum6 = 1
  39.       irot = 1
  40.       iorflg = 2
  41.       imx = 20
  42.       imy = 20
  43.       imz = 20
  44. cc    if (ineum5 .ne. 1 .or. ineum6 .ne. 1) ising=0
  45.       ising = 0
  46. cc    imx = 5
  47. cc    imy = 5
  48. cc    imz = 5
  49.       n = imx*imy*imz
  50. c     write(6,*)   ' *********** problem type *************'
  51. c     if( ineum5 .eq. 0 ) then
  52. c        write(6,*)' *****       dir on bottom        *****'
  53. c     else
  54. c        write(6,*)' *****     neuman on bottom       *****'
  55. c     endif
  56. c     if( ineum6 .eq. 0 ) then
  57. c        write(6,*)' *****         dir on top         *****'
  58. c     else
  59. c        write(6,*)' *****      neuman on top         *****'
  60. c     endif
  61. c     if( ising .eq. 0 ) then
  62. c        write(6,*)' *****         regular            *****'
  63. c     else
  64. c        write(6,*)' ***** singular if neuman on top and bottom *****'
  65. c     endif
  66. c     write(6,*)   ' ***** mesh cells in x dir',imx,'     *****'
  67. c     write(6,*)   ' ***** mesh cells in y dir',imy,'     *****'
  68. c     write(6,*)   ' ***** mesh cells in z dir',imz,'     *****'
  69. c
  70. c     ifli is the number of fillin stripes allowed for each of the
  71. c          inner stripes; if zero no fillin.
  72. c     iflm is the number of fillin stripes allowed for each of the
  73. c          middle stripes; if zero no fillin.
  74. c     iflo is the number of fillin stripes allowed for each of the
  75. c          outer stripes; if zero no fillin here.
  76. c     inum5 if 1 then neumann on bottom
  77. c           if 0 then dirchlet on bottom
  78. c     inum6 if 1 then neumann on top
  79. c           if 0 then dirchlet on top
  80. c     irot  if 0 then no rot flow field
  81. c           if 1 then rot flow field
  82. c     ising if zero regular
  83. c           if 1 then signular if neumann top and bottom
  84. c     imx # of mesh cells in the x direction
  85. c     imy # of mesh cells in the y direction
  86. c     imz # of mesh cells in the z direction
  87. cc    ifli = 0
  88. cc    iflm = 0
  89. cc    iflo = 0
  90. cc    write(6,*)' call prbtyp'
  91.       call prbtyp(ineum5,ineum6,ising,imx,imy,imz,0)
  92. cc    write(6,*)' call matgen'
  93.       ti1 = second(ii)
  94.       call matgen(ifli,iflm,iflo,irot,nonz,ia,ja,a,b)
  95. c     write(6,*)'n,nonz,ia(n+1)'
  96. c     write(6,*)n,nonz,ia(n+1)
  97. cc    write(6,*)' after matgen'
  98.       ti2 = second(ii) - ti1
  99.       if( ia(n+1) .gt. loca ) then
  100.          write(6,*)' not enough storage',loca,ia(n+1)
  101.          stop
  102.       endif
  103. c      stop
  104.       job = 0
  105.       anrm = abs(a(isamax(ia(n+1)-1,a,1)))
  106.       call scopy(n,b,1,t2,1)
  107.       maxits = n
  108.       tol = 1.0e-6
  109.       write(6,101) ti2
  110.   101 format(/20x,'time to generate matrix = ',5x,1pe10.3)
  111.       do 888 ics = 1,3
  112.       ti3 = second(ii)
  113.       do 777 mm = 1, nit(ics)
  114.       call scopy(n,t2,1,x,1)
  115.       call scopy(n,t2,1,b,1)
  116.       call iccglu(a,n,ia,ja,af,b,x,g,p,t1,tol,maxits,its,job,info)
  117. c     write(6,*)'info should be zero  info = ',info
  118.       job = 1
  119.   777 continue
  120.       ti4 = second(ii) - ti3
  121.       call scopy(n,t2,1,b,1)
  122.       call cgres(a,n,ia,ja,x,b,p)
  123.       resd = abs(p(isamax(n,p,1)))
  124.       xnrm = abs(x(isamax(n,x,1)))
  125. c     write(6,*)'anrm,xnrm,resd',anrm,xnrm,resd
  126.       sres = resd/(anrm*xnrm)
  127.       nonzr = ia(n+1) - 1
  128. c     ti5 = ti2 + ti4
  129. c     write(6,100) sres,ti5,ti2,ti4,nonzr,its
  130. c 100 format(20x,'scaled residual = ',13x,1pe10.3,
  131. c    1      /20x,'total time = ',18x,1pe10.3,
  132. c    2      /20x,'time to generate matrix = ',5x,1pe10.3,
  133. c    3      /20x,'time for cg iterations = ',6x,1pe10.3,
  134. c    4      /20x,'number of nonzero elements = ',2x,i10,
  135. c    5      /20x,'number of cg iterations = ',5x,i10)
  136.       write(6,102) nit(ics),its,sres,ti4
  137.   102 format(20x,'results for ',i3,' sets of ',i4,' cg iterations ',
  138.      1      'for each set',
  139.      2      //20x,'scaled residual = ',13x,1pe10.3,
  140.      3      /20x,'time for cg iterations = ',6x,1pe10.3,//)
  141.   888 continue
  142. c     go to 1
  143.       stop
  144.       end
  145.        subroutine matgen(ifli,iflm,iflo,irot,nonz,ia,ja,a,f)
  146.       implicit real(a-h,o-z)
  147.       integer ia(1),ja(1),ifli,iflo
  148.       real a(1)
  149.       integer bwi,bwo
  150.       real f(28000),acof0(28000),acof1(28000),acof2(28000),
  151.      # acof3(28000),
  152.      # acof4(28000),acof5(28000),acof6(28000),gl(1000),gu(1000)
  153.        real cvx(30,30,30),cvy(30,30,30),cvz(30,30,30)
  154.      #  ,omg(30,30,30)
  155.        common/coef/acof0,acof1,acof2,acof3,acof4,acof5,acof6
  156.        common /order/ iorflg
  157. c      ineum5=1 neuman on bot;=0 dir on bot.
  158. c      ineum6=1 neuman on top;=0 dir on top.
  159. c      irot = 1, rotational flow field
  160. c      irot = 0, non-rotational flow field
  161.       flx=1.e0
  162.       fly=1.e0
  163.       flz=1.e0
  164. c      write(6,*)' call prbtyp'
  165.        call prbtyp(ineum5,ineum6,ising,imx,jmx,kmx,1)
  166. c      write(6,*)' out of prbtyp in matgen'
  167.       id=1
  168.       idp1=id+1
  169.        iptflg=0
  170.        go to (3,5,7),iorflg
  171. 3     continue
  172. c      write(6,*)' continue 3'
  173.        bwo=imx*jmx
  174.        bwi=imx
  175.        ni=1
  176.        nj=bwi
  177.        nk=bwo
  178.        nc=-bwo-bwi
  179.        nib=1
  180.        njb=imx
  181.        ncb=-imx
  182. c       (ijk) (5310246)
  183.        go to 9
  184. 5     continue
  185. c      write(6,*)' continue 5'
  186. c       (kij) (3150624)
  187.        bwo=kmx*imx
  188.        bwi=kmx
  189.        ni=bwi
  190.        nj=bwo
  191.        nk=1
  192.        nc=-bwo-bwi
  193.        nib=1
  194.        njb=imx
  195.        ncb=-imx
  196.        go to 9
  197. 7     continue
  198. c      write(6,*)' continue 7'
  199. c       (jki) (1530462)
  200.        bwo=jmx*kmx
  201.        bwi=jmx
  202.        ni=bwo
  203.        nj=1
  204.        nk=bwi
  205.        nc=-bwo-bwi
  206.        nib=jmx
  207.        njb=1
  208.        ncb=-jmx
  209. 9     continue
  210. c      write(6,*)' continue 9'
  211. c      write(6,*)'imx,jmx,kmx',imx,jmx,kmx
  212.       dx=flx/float(imx)
  213.       dy=fly/float(jmx)
  214.       dz=flz/float(kmx)
  215.       rdx2=1.e0/dx**2
  216.       rdy2=1.e0/dy**2
  217.       rdz2=1.e0/dz**2
  218.       mx=imx*jmx*kmx
  219.       imxm1=imx-1
  220.       jmxm1=jmx-1
  221.       kmxm1=kmx-1
  222.       nonz=3*mx-2+2*(mx-bwi+ifli)+2*(mx-bwo+iflo)
  223.       nonzt=nonz
  224. c      write(6,*)' call inits'
  225.       call inits(a,mx,ia,ja)
  226.       if(ifli .ge. bwi-1) go to 220
  227.       if(iflo .ge. bwo-bwi) go to 220
  228.       do 10 m=1,mx
  229.       f(m)=0.e0
  230.   10  continue
  231. c      write(6,*)' continue 10'
  232.       do 11 i=1,imx
  233.       do 11 j=1,jmx
  234.       do 11 k=1,kmx
  235.       xi=(float(i)-0.5e0)*dx
  236.       yj=(float(j)-0.5e0)*dy
  237.       zk=(float(k)-0.5e0)*dz
  238.       facx = 1.0e0
  239.       facy = 1.0e0
  240.       if( irot .eq. 0 ) go to 12
  241.       facx = xi - .05e0
  242.       facy = yj - .05e0
  243.    12 continue
  244.       dum=32.0e0*xi*(1.e0-xi)*yj*(1.e0-yj)*zk
  245.       dum1=2.0e0*xi*yj*zk**2
  246.        dum=25.e0*dum
  247.        dum1=2.0e0*dum1
  248.        cvx(i,j,k)=dum*facx
  249.        cvy(i,j,k)=dum*facy
  250.        cvz(i,j,k)=dum1
  251.        omg(i,j,k)=0.e0
  252.        dum2 = (xi*xi)*yj*zk
  253.        m = i*ni + j*nj + k*nk + nc
  254.        f(m) = dum2
  255. 11    continue
  256. c      write(6,*)' continue 11'
  257.       do 15 j=1,jmx
  258.       do 15 i=1,imx
  259.       mb=i*nib+j*njb+ncb
  260.       gl(mb)=1.e0
  261.       gu(mb)=2.0e0
  262.   15  continue
  263. c      write(6,*)' continue 15'
  264.       do 20 m=1,mx
  265.       acof0(m)=0.e0
  266.       acof1(m)=0.e0
  267.       acof2(m)=0.e0
  268.       acof3(m)=0.e0
  269.       acof4(m)=0.e0
  270.       acof5(m)=0.e0
  271.       acof6(m)=0.e0
  272.   20  continue
  273. c      write(6,*)' continue 20'
  274.       if(imx .lt. 3) go to 45
  275.       if(jmx .lt. 3) go to 45
  276.       if(kmx .lt. 3) go to 45
  277.       do 30 j=2,jmxm1
  278.       do 30 i=2,imxm1
  279.       do 30 k=2,kmxm1
  280.       m=i*ni+j*nj+k*nk+nc
  281.       acof0(m)=2.0e0*(rdx2+rdy2+rdz2)+omg(i,j,k)
  282.       acof1(m)=-rdx2-0.5e0*cvx(i,j,k)/dx
  283.       acof2(m)=-rdx2+0.5e0*cvx(i,j,k)/dx
  284.       acof3(m)=-rdy2-0.5e0*cvy(i,j,k)/dy
  285.       acof4(m)=-rdy2+0.5e0*cvy(i,j,k)/dy
  286.       acof5(m)=-rdz2-0.5e0*cvz(i,j,k)/dz
  287.       acof6(m)=-rdz2+0.5e0*cvz(i,j,k)/dz
  288.   30  continue
  289. c      write(6,*)' continue 30'
  290.   45  continue
  291. c      write(6,*)' continue 45'
  292.       if((jmx.lt.3).or.(kmx.lt.3)) go to 55
  293.       do 50 j=2,jmxm1
  294.       do 50 k=2,kmxm1
  295.       i=1
  296.       m=i*ni+j*nj+k*nk+nc
  297.       acof0(m)=rdx2+2.0e0*(rdy2+rdz2)+omg(i,j,k)-0.5e0*cvx(i,j,k)/dx
  298.       acof2(m)=-rdx2+0.5e0*cvx(i,j,k)/dx
  299.       acof3(m)=-rdy2-0.5e0*cvy(i,j,k)/dy
  300.       acof4(m)=-rdy2+0.5e0*cvy(i,j,k)/dy
  301.       acof5(m)=-rdz2-0.5e0*cvz(i,j,k)/dz
  302.       acof6(m)=-rdz2+0.5e0*cvz(i,j,k)/dz
  303.       i=imx
  304.       m=i*ni+j*nj+k*nk+nc
  305.       acof0(m)=rdx2+2.0e0*(rdy2+rdz2)+omg(i,j,k) +0.5e0*cvx(i,j,k)/dx
  306.       acof1(m)=-rdx2-0.5e0*cvx(i,j,k)/dx
  307.       acof3(m)=-rdy2-0.5e0*cvy(i,j,k)/dy
  308.       acof4(m)=-rdy2+0.5e0*cvy(i,j,k)/dy
  309.       acof5(m)=-rdz2-0.5e0*cvz(i,j,k)/dz
  310.       acof6(m)=-rdz2+0.5e0*cvz(i,j,k)/dz
  311.   50  continue
  312. c      write(6,*)' continue 50'
  313.   55  continue
  314. c      write(6,*)' continue 55'
  315.       if((imx.lt.3).or.(kmx.lt.3)) go to 65
  316.       do 60 i=2,imxm1
  317.       do 60 k=2,kmxm1
  318.       j=1
  319.       m=i*ni+j*nj+k*nk+nc
  320.       acof0(m)=rdy2+ 2.0e0*(rdx2+rdz2)+omg(i,j,k) -0.5e0*cvy(i,j,k)/dy
  321.       acof1(m)=-rdx2-0.5e0*cvx(i,j,k)/dx
  322.       acof2(m)=-rdx2+0.5e0*cvx(i,j,k)/dx
  323.       acof4(m)=-rdy2+0.5e0*cvy(i,j,k)/dy
  324.       acof5(m)=-rdz2-0.5e0*cvz(i,j,k)/dz
  325.       acof6(m)=-rdz2+0.5e0*cvz(i,j,k)/dz
  326.       j=jmx
  327.       m=i*ni+j*nj+k*nk+nc
  328.       acof0(m)=rdy2+2.0e0*(rdx2+rdz2)+omg(i,j,k)+0.5e0*cvy(i,j,k)/dy
  329.       acof1(m)=-rdx2-0.5e0*cvx(i,j,k)/dx
  330.       acof2(m)=-rdx2+0.5e0*cvx(i,j,k)/dx
  331.       acof3(m)=-rdy2-0.5e0*cvy(i,j,k)/dy
  332.       acof5(m)=-rdz2-0.5e0*cvz(i,j,k)/dz
  333.       acof6(m)=-rdz2+0.5e0*cvz(i,j,k)/dz
  334.   60  continue
  335. c      write(6,*)' continue 60'
  336.   65  continue
  337. c      write(6,*)' continue 65'
  338.       if((imx.lt.3).or.(jmx.lt.3)) go to 75
  339.       do 70 i=2,imxm1
  340.       do 70 j=2,jmxm1
  341.       k=1
  342.       m=(j-1)*bwo+(i-1)*bwi +k
  343.       acof0(m)=2.0e0*(rdx2+rdy2)+3.0e0*rdz2 +omg(i,j,k)
  344.      #  +cvz(i,j,k)/(2.0e0*dz)
  345.       if (ineum5 .eq. 1) acof0(m) = acof0(m) - 2.0e0*rdz2 -cvz(i,j,k)/dz
  346.       acof1(m)=-rdx2-0.5e0*cvx(i,j,k)/dx
  347.       acof2(m)=-rdx2+0.5e0*cvx(i,j,k)/dx
  348.       acof3(m)=-rdy2-0.5e0*cvy(i,j,k)/dy
  349.       acof4(m)=-rdy2+0.5e0*cvy(i,j,k)/dy
  350.       acof6(m)=-rdz2+0.5e0*cvz(i,j,k)/dz
  351.       if (ineum5 .eq. 1) go to 71
  352.       mb=i*nib+j*njb+ncb
  353.       f(m)=f(m)+(2.0e0*rdz2+cvz(i,j,k)/dz)*gl(mb)
  354.    71 continue
  355. c      write(6,*)' continue 71'
  356.       k=kmx
  357.       m=i*ni+j*nj+k*nk+nc
  358.       acof0(m)=2.0e0*(rdx2+rdy2)+3.0e0*rdz2+omg(i,j,k)
  359.      #  -cvz(i,j,k)/(2.0e0*dz)
  360.       if (ineum6 .eq. 1) acof0(m) = acof0(m) - 2.0e0*rdz2 +cvz(i,j,k)/dz
  361.       acof1(m)=-rdx2-0.5e0*cvx(i,j,k)/dx
  362.       acof2(m)=-rdx2+0.5e0*cvx(i,j,k)/dx
  363.       acof3(m)=-rdy2-0.5e0*cvy(i,j,k)/dy
  364.       acof4(m)=-rdy2+0.5e0*cvy(i,j,k)/dy
  365.       acof5(m)=-rdz2-0.5e0*cvz(i,j,k)/dz
  366.       if (ineum6 .eq. 1) go to 72
  367.       mb=i*nib+j*njb+ncb
  368.       f(m)=f(m)+(2.0e0*rdz2-cvz(i,j,k)/dz)*gu(mb)
  369.    72 continue
  370. c      write(6,*)' continue 72'
  371.   70  continue
  372. c      write(6,*)' continue 70'
  373.   75  continue
  374. c      write(6,*)' continue 75'
  375.       if(kmx.lt.3) go to 85
  376.       do 80 k=2,kmxm1
  377.       i=1
  378.       j=1
  379.       m=i*ni+j*nj+k*nk+nc
  380.       acof0(m)=rdx2+rdy2+2.0e0*rdz2+omg(i,j,k)
  381.      #  -0.5e0*cvx(i,j,k)/dx-0.5e0*cvy(i,j,k)/dy
  382.       acof2(m)=-rdx2+0.5e0*cvx(i,j,k)/dx
  383.       acof4(m)=-rdy2+0.5e0*cvy(i,j,k)/dy
  384.       acof5(m)=-rdz2-0.5e0*cvz(i,j,k)/dz
  385.       acof6(m)=-rdz2+0.5e0*cvz(i,j,k)/dz
  386.       j=jmx
  387.       m=i*ni+j*nj+k*nk+nc
  388.       acof0(m)=rdx2+rdy2+2.0e0*rdz2+omg(i,j,k)
  389.      #  -0.5e0*cvx(i,j,k)/dx+0.5e0*cvy(i,j,k)/dy
  390.       acof2(m)=-rdx2+0.5e0*cvx(i,j,k)/dx
  391.       acof3(m)=-rdy2-0.5e0*cvy(i,j,k)/dy
  392.       acof5(m)=-rdz2-0.5e0*cvz(i,j,k)/dz
  393.       acof6(m)=-rdz2+0.5e0*cvz(i,j,k)/dz
  394.       i=imx
  395.       m=(j-1)*bwo+(i-1)*bwi +k
  396.       acof0(m)=rdx2+rdy2+2.0e0*rdz2+omg(i,j,k)
  397.      #  +0.5e0*cvx(i,j,k)/dx+0.5e0*cvy(i,j,k)/dy
  398.       acof1(m)=-rdx2-0.5e0*cvx(i,j,k)/dx
  399.       acof3(m)=-rdy2-0.5e0*cvy(i,j,k)/dy
  400.       acof5(m)=-rdz2-0.5e0*cvz(i,j,k)/dz
  401.       acof6(m)=-rdz2+ 0.5e0*cvz(i,j,k)/dz
  402.       j=1
  403.       m=i*ni+j*nj+k*nk+nc
  404.       acof0(m)=rdx2+rdy2+2.0e0*rdz2+omg(i,j,k)
  405.      #  +0.5e0*cvx(i,j,k)/dx-0.5e0*cvy(i,j,k)/dy
  406.       acof1(m)=-rdx2-0.5e0*cvx(i,j,k)/dx
  407.       acof4(m)=-rdy2+0.5e0*cvy(i,j,k)/dy
  408.       acof5(m)=-rdz2-0.5e0*cvz(i,j,k)/dz
  409.       acof6(m)=-rdz2+0.5e0*cvz(i,j,k)/dz
  410.   80  continue
  411. c      write(6,*)' continue 80'
  412.   85  continue
  413. c      write(6,*)' continue 85'
  414.       if(imx.lt.3)go to 95
  415.       do 90 i=2,imxm1
  416.       k=1
  417.       j=1
  418.       m=i*ni+j*nj+k*nk+nc
  419.       acof0(m)=2.0e0*rdx2+rdy2+3.0e0*rdz2+omg(i,j,k)
  420.      #  -0.5e0*cvy(i,j,k)/dy+0.5e0*cvz(i,j,k)/dz
  421.       if (ineum5 .eq. 1) acof0(m) = acof0(m) - 2.0e0*rdz2 -cvz(i,j,k)/dz
  422.       acof1(m)=-rdx2-0.5e0*cvx(i,j,k)/dx
  423.       acof2(m)=-rdx2+0.5e0*cvx(i,j,k)/dx
  424.       acof4(m)=-rdy2+0.5e0*cvy(i,j,k)/dy
  425.       acof6(m)=-rdz2+0.5e0*cvz(i,j,k)/dz
  426.       if (ineum5 .eq. 1) go to 91
  427.       mb=i*nib+j*njb+ncb
  428.       f(m)=f(m)+(2.0e0*rdz2+cvz(i,j,k)/dz)*gl(mb)
  429.    91 continue
  430. c      write(6,*)' continue 91'
  431.       j=jmx
  432.       m=i*ni+j*nj+k*nk+nc
  433.       acof0(m)=2.0e0*rdx2 +rdy2 +3.0e0*rdz2+omg(i,j,k)
  434.      #  +0.5e0*cvy(i,j,k)/dy+0.5e0*cvz(i,j,k)/dz
  435.       if (ineum5 .eq. 1) acof0(m) = acof0(m) - 2.0e0*rdz2 -cvz(i,j,k)/dz
  436.       acof1(m)=-rdx2-0.5e0*cvx(i,j,k)/dx
  437.       acof2(m)=-rdx2+0.5e0*cvx(i,j,k)/dx
  438.       acof3(m)=-rdy2-0.5e0*cvy(i,j,k)/dy
  439.       acof6(m)=-rdz2+0.5e0*cvz(i,j,k)/dz
  440.       if (ineum5 .eq. 1) go to 92
  441.       mb=i*nib+j*njb+ncb
  442.       f(m)=f(m)+(2.0e0*rdz2+ cvz(i,j,k)/dz)*gl(mb)
  443.    92 continue
  444. c      write(6,*)' continue 92'
  445.       k=kmx
  446.       m=i*ni+j*nj+k*nk+nc
  447.       acof0(m)=2.0e0*rdx2+rdy2+3.0e0*rdz2+omg(i,j,k)
  448.      #  +0.5e0*cvy(i,j,k)/dy-0.5e0*cvz(i,j,k)/dz
  449.       if (ineum6 .eq. 1) acof0(m) = acof0(m) - 2.0e0*rdz2 +cvz(i,j,k)/dz
  450.       acof1(m)=-rdx2-0.5e0*cvx(i,j,k)/dx
  451.       acof2(m)=-rdx2+0.5e0*cvx(i,j,k)/dx
  452.       acof3(m)=-rdy2-0.5e0*cvy(i,j,k)/dy
  453.       acof5(m)=-rdz2-0.5e0*cvz(i,j,k)/dz
  454.       if (ineum6 .eq. 1) go to 93
  455.       mb=i*nib+j*njb+ncb
  456.       f(m)=f(m)+(2.0e0*rdz2-cvz(i,j,k)/dz)*gu(mb)
  457.    93 continue
  458. c      write(6,*)' continue 93'
  459.       j=1
  460.       m=(j-1)*bwo+(i-1)*bwi +k
  461.       acof0(m)=2.0e0*rdx2+rdy2+3.0e0*rdz2+omg(i,j,k)
  462.      #  -0.5e0*cvy(i,j,k)/dy-0.5e0*cvz(i,j,k)/dz
  463.       if (ineum6 .eq. 1) acof0(m) = acof0(m) - 2.0e0*rdz2 +cvz(i,j,k)/dz
  464.       acof1(m)=-rdx2-0.5e0*cvx(i,j,k)/dx
  465.       acof2(m)=-rdx2+0.5e0*cvx(i,j,k)/dx
  466.       acof4(m)=-rdy2+0.5e0*cvy(i,j,k)/dy
  467.       acof5(m)=-rdz2-0.5e0*cvz(i,j,k)/dz
  468.       if (ineum6 .eq. 1) go to 94
  469.       mb=i*nib+j*njb+ncb
  470.       f(m)=f(m)+(2.0e0*rdz2-cvz(i,j,k)/dz)*gu(mb)
  471.    94 continue
  472. c      write(6,*)' continue 94'
  473.   90  continue
  474. c      write(6,*)' continue 90'
  475.   95  continue
  476. c      write(6,*)' continue 95'
  477.       if(jmx.lt.3)go to 105
  478.       do 100 j=2,jmxm1
  479.       k=1
  480.       i=1
  481.       m=i*ni+j*nj+k*nk+nc
  482.       acof0(m)=rdx2+ 2.0e0*rdy2+3.0e0*rdz2+omg(i,j,k)
  483.      # -0.5e0*cvx(i,j,k)/dx+0.5e0*cvz(i,j,k)/dz
  484.       if (ineum5 .eq. 1) acof0(m) = acof0(m) - 2.0e0*rdz2 -cvz(i,j,k)/dz
  485.       acof2(m)=-rdx2+0.5e0*cvx(i,j,k)/dx
  486.       acof3(m)=-rdy2-0.5e0*cvy(i,j,k)/dy
  487.       acof4(m)=-rdy2+0.5e0*cvy(i,j,k)/dy
  488.       acof6(m)=-rdz2+0.5e0*cvz(i,j,k)/dz
  489.       if (ineum5 .eq. 1) go to 101
  490.       mb=i*nib+j*njb+ncb
  491.       f(m)=f(m)+(2.0e0*rdz2+cvz(i,j,k)/dz)*gl(mb)
  492.   101 continue
  493. c      write(6,*)' continue 101'
  494.       i=imx
  495.       m=i*ni+j*nj+k*nk+nc
  496.       acof0(m)=rdx2+2.0e0*rdy2+3.0e0*rdz2+omg(i,j,k)
  497.      # +0.5e0*cvx(i,j,k)/dx+0.5e0*cvz(i,j,k)/dz
  498.       if (ineum5 .eq. 1) acof0(m) = acof0(m) - 2.0e0*rdz2 -cvz(i,j,k)/dz
  499.       acof1(m)=-rdx2-0.5e0*cvx(i,j,k)/dx
  500.       acof3(m)=-rdy2-0.5e0*cvy(i,j,k)/dy
  501.       acof4(m)=-rdy2+0.5e0*cvy(i,j,k)/dy
  502.       acof6(m)=-rdz2+0.5e0*cvz(i,j,k)/dz
  503.       if (ineum5 .eq. 1) go to 102
  504.       mb=i*nib+j*njb+ncb
  505.       f(m)=f(m)+(2.0e0*rdz2+cvz(i,j,k)/dz)*gl(mb)
  506.   102 continue
  507. c      write(6,*)' continue 102'
  508.       k=kmx
  509.       m=i*ni+j*nj+k*nk+nc
  510.       acof0(m)=rdx2+2.0e0*rdy2+3.0e0*rdz2+omg(i,j,k)
  511.      # +0.5e0*cvx(i,j,k)/dx-0.5e0*cvz(i,j,k)/dz
  512.       if (ineum6 .eq. 1) acof0(m) = acof0(m) - 2.0e0*rdz2 +cvz(i,j,k)/dz
  513.       acof1(m)=-rdx2-0.5e0*cvx(i,j,k)/dx
  514.       acof3(m)=-rdy2-0.5e0*cvy(i,j,k)/dy
  515.       acof4(m)=-rdy2+0.5e0*cvy(i,j,k)/dy
  516.       acof5(m)=-rdz2-0.5e0*cvz(i,j,k)/dz
  517.       if (ineum6 .eq. 1) go to 103
  518.       mb=i*nib+j*njb+ncb
  519.       f(m)=f(m)+(2.0e0*rdz2-cvz(i,j,k)/dz)*gu(mb)
  520.   103 continue
  521. c      write(6,*)' continue 103'
  522.       i=1
  523.       m=i*ni+j*nj+k*nk+nc
  524.       acof0(m)=rdx2+2.0e0*rdy2+3.0e0*rdz2+omg(i,j,k)
  525.      # -0.5e0*cvx(i,j,k)/dx-0.5e0*cvz(i,j,k)/dz
  526.       if (ineum6 .eq. 1) acof0(m) = acof0(m) - 2.0e0*rdz2 +cvz(i,j,k)/dz
  527.       acof2(m)=-rdx2+0.5e0*cvx(i,j,k)/dx
  528.       acof3(m)=-rdy2-0.5e0*cvy(i,j,k)/dy
  529.       acof4(m)=-rdy2+0.5e0*cvy(i,j,k)/dy
  530.       acof5(m)=-rdz2-0.5e0*cvz(i,j,k)/dz
  531.       if (ineum6 .eq. 1) go to 104
  532.       mb=i*nib+j*njb+ncb
  533.       f(m)=f(m)+(2.0e0*rdz2-cvz(i,j,k)/dz)*gu(mb)
  534.   104 continue
  535. c      write(6,*)' continue 104'
  536. 100  continue
  537. c      write(6,*)' continue 100'
  538. 105  continue
  539. c      write(6,*)' continue 105'
  540.       i=1
  541.       j=1
  542.       k=1
  543.       m=i*ni+j*nj+k*nk+nc
  544.       acof0(m)=rdx2+rdy2+3.0e0*rdz2+omg(i,j,k)
  545.      #  -0.5e0*cvx(i,j,k)/dx-0.5e0*cvy(i,j,k)/dy
  546.      # +0.5e0*cvz(i,j,k)/dz
  547.       if (ineum5 .eq. 1) acof0(m) = acof0(m) - 2.0e0*rdz2 -cvz(i,j,k)/dz
  548.       acof2(m)=-rdx2+0.5e0*cvx(i,j,k)/dx
  549.       acof4(m)=-rdy2+0.5e0*cvy(i,j,k)/dx
  550.       acof6(m)=-rdz2+0.5e0*cvz(i,j,k)/dz
  551.       if (ineum5 .eq. 1) go to 106
  552.       mb=i*nib+j*njb+ncb
  553.       f(m)=f(m)+(2.0e0*rdz2+cvz(i,j,k)/dz)*gl(mb)
  554.   106 continue
  555. c      write(6,*)' continue 106'
  556.       k=kmx
  557.       m=i*ni+j*nj+k*nk+nc
  558.       acof0(m)=rdx2+rdy2+3.0e0*rdz2+omg(i,j,k)
  559.      #  -0.5e0*cvx(i,j,k)/dx-0.5e0*cvy(i,j,k)/dy
  560.      # -0.5e0*cvz(i,j,k)/dz
  561.       if (ineum6 .eq. 1) acof0(m) = acof0(m) - 2.0e0*rdz2 +cvz(i,j,k)/dz
  562.       acof2(m)=-rdx2+0.5e0*cvx(i,j,k)/dx
  563.       acof4(m)=-rdy2+0.5e0*cvy(i,j,k)/dy
  564.       acof5(m)=-rdz2-0.5e0*cvz(i,j,k)/dz
  565.       if (ineum6. eq. 1) go to 107
  566.       mb=i*nib+j*njb+ncb
  567.       f(m)=f(m)+(2.0e0*rdz2-cvz(i,j,k)/dz)*gu(mb)
  568.   107 continue
  569. c      write(6,*)' continue 107'
  570.       i=1
  571.       j=jmx
  572.       k=1
  573.       m=i*ni+j*nj+k*nk+nc
  574.       acof0(m)=rdx2+rdy2+3.0e0*rdz2+omg(i,j,k)
  575.      #  -0.5e0*cvx(i,j,k)/dx+0.5e0*cvy(i,j,k)/dy
  576.      # +0.5e0*cvz(i,j,k)/dz
  577.       if (ineum5 .eq. 1) acof0(m) = acof0(m) - 2.0e0*rdz2 -cvz(i,j,k)/dz
  578.       acof2(m)=-rdx2+0.5e0*cvx(i,j,k)/dx
  579.       acof3(m)=-rdy2-0.5e0*cvy(i,j,k)/dy
  580.       acof6(m)=-rdz2+0.5e0*cvz(i,j,k)/dz
  581.       if (ineum5 .eq. 1) go to 108
  582.       mb=i*nib+j*njb+ncb
  583.       f(m)=f(m)+(2.0e0*rdz2+cvz(i,j,k)/dz)*gl(mb)
  584.   108 continue
  585. c      write(6,*)' continue 108'
  586.       k=kmx
  587.       m=i*ni+j*nj+k*nk+nc
  588.       acof0(m)=rdx2+rdy2+3.0e0*rdz2+omg(i,j,k)
  589.      #  -0.5e0*cvx(i,j,k)/dx+0.5e0*cvy(i,j,k)/dy
  590.      # -0.5e0*cvz(i,j,k)/dz
  591.       if (ineum6 .eq. 1) acof0(m) = acof0(m) - 2.0e0*rdz2 +cvz(i,j,k)/dz
  592.       acof2(m)=-rdx2+0.5e0*cvx(i,j,k)/dx
  593.       acof3(m)=-rdy2-0.5e0*cvy(i,j,k)/dy
  594.       acof5(m)=-rdz2-0.5e0*cvz(i,j,k)/dz
  595.       if (ineum6 .eq. 1) go to 109
  596.       mb=i*nib+j*njb+ncb
  597.       f(m)=f(m)+(2.0e0*rdz2-cvz(i,j,k)/dz)*gu(mb)
  598.   109 continue
  599. c      write(6,*)' continue 109'
  600.       i=imx
  601.       j=1
  602.       k=1
  603.       m=i*ni+j*nj+k*nk+nc
  604.       acof0(m)=rdx2+rdy2+3.0e0*rdz2+omg(i,j,k)
  605.      #  +0.5e0*cvx(i,j,k)/dx-0.5e0*cvy(i,j,k)/dy
  606.      # +0.5e0*cvz(i,j,k)/dz
  607.       if (ineum5 .eq. 1) acof0(m) = acof0(m) - 2.0e0*rdz2 -cvz(i,j,k)/dz
  608.       acof1(m)=-rdx2-0.5e0*cvx(i,j,k)/dx
  609.       acof4(m)=-rdy2+0.5e0*cvy(i,j,k)/dy
  610.       acof6(m)=-rdz2+0.5e0*cvz(i,j,k)/dz
  611.       if (ineum5 .eq. 1) go to 111
  612.       mb=i*nib+j*njb+ncb
  613.       f(m)=f(m)+(2.0e0*rdz2+cvz(i,j,k)/dz)*gl(mb)
  614.   111 continue
  615. c      write(6,*)' continue 111'
  616.       k=kmx
  617.       m=i*ni+j*nj+k*nk+nc
  618.       acof0(m)=rdx2+rdy2+3.0e0*rdz2+omg(i,j,k)
  619.      #  +0.5e0*cvx(i,j,k)/dx-0.5e0*cvy(i,j,k)/dy
  620.      # -0.5e0*cvz(i,j,k)/dz
  621.       if (ineum6 .eq. 1) acof0(m) = acof0(m) - 2.0e0*rdz2 +cvz(i,j,k)/dz
  622.       acof1(m)=-rdx2-0.5e0*cvx(i,j,k)/dx
  623.       acof4(m)=-rdy2+0.5e0*cvy(i,j,k)/dy
  624.       acof5(m)=-rdz2-0.5e0*cvz(i,j,k)/dz
  625.       if (ineum6 .eq. 1) go to 112
  626.       mb=i*nib+j*njb+ncb
  627.       f(m)=f(m)+(2.0e0*rdz2-cvz(i,j,k)/dz)*gu(mb)
  628.   112 continue
  629. c      write(6,*)' continue 112'
  630.       i=imx
  631.       j=jmx
  632.       k=1
  633.       m=i*ni+j*nj+k*nk+nc
  634.       acof0(m)=rdx2+rdy2+3.0e0*rdz2+omg(i,j,k)
  635.      #  +0.5e0*cvx(i,j,k)/dx+0.5e0*cvy(i,j,k)/dy
  636.      # +0.5e0*cvz(i,j,k)/dz
  637.       if (ineum5 .eq. 1) acof0(m) = acof0(m) - 2.0e0*rdz2 -cvz(i,j,k)/dz
  638.       acof1(m)=-rdx2-0.5e0*cvx(i,j,k)/dx
  639.       acof3(m)=-rdy2-0.5e0*cvy(i,j,k)/dy
  640.       acof6(m)=-rdz2+0.5e0*cvz(i,j,k)/dz
  641.       if (ineum5 .eq. 1) go to 113
  642.       mb=i*nib+j*njb+ncb
  643.       f(m)=f(m)+(2.0e0*rdz2+cvz(i,j,k)/dz)*gl(mb)
  644.   113 continue
  645. c      write(6,*)' continue 113'
  646.       k=kmx
  647.       m=i*ni+j*nj+k*nk+nc
  648.       acof0(m)=rdx2+rdy2+3.0e0*rdz2+omg(i,j,k)
  649.      #  +0.5e0*cvx(i,j,k)/dx+0.5e0*cvy(i,j,k)/dy
  650.      # -0.5e0*cvz(i,j,k)/dz
  651.       if (ineum6 .eq. 1) acof0(m) = acof0(m) - 2.0e0*rdz2 +cvz(i,j,k)/dz
  652.       acof1(m)=-rdx2-0.5e0*cvx(i,j,k)/dx
  653.       acof3(m)=-rdy2-0.5e0*cvy(i,j,k)/dy
  654.       acof5(m)=-rdz2-0.5e0*cvz(i,j,k)/dz
  655.       if (ineum6 .eq. 1) go to 114
  656.       mb=i*nib+j*njb+ncb
  657.       f(m)=f(m)+(2.0e0*rdz2-cvz(i,j,k)/dz)*gu(mb)
  658.   114 continue
  659. c      write(6,*)' continue 114'
  660.        if(ineum5*ineum6 .eq. 0) go to 117
  661.        if( ising .eq. 1 ) go to 117
  662.        i=1
  663.        j=1
  664.        k=1
  665.        m=i*ni+j*nj+k*nk+nc
  666.        acof2(m)=0.e0
  667.        acof4(m)=0.e0
  668.        acof6(m)=0.e0
  669.        f(m)=0.e0
  670.        i=2
  671.        m=i*ni+j*nj+k*nk+nc
  672.        acof1(m)=0.e0
  673.        i=1
  674.        j=2
  675.        m=i*ni+j*nj+k*nk+nc
  676.        acof3(m)=0.e0
  677.        j=1
  678.        k=2
  679.        m=i*ni+j*nj+k*nk+nc
  680.        acof5(m)=0.e0
  681. 117    continue
  682. c      write(6,*)' continue 117'
  683. c  load coef
  684. c      write(6,*)'load matrix'
  685.       do 150 i=1+bwo,mx
  686.              j=i-bwo
  687.              t=acof3(i)
  688.              call put(t,a,mx,ia,ja,i,j)
  689. 150   continue
  690. c      write(6,*)' continue 150'
  691.        do 155 i=1+bwi,mx
  692.               j=i-bwi
  693.               t=acof1(i)
  694.               call put(t,a,mx,ia,ja,i,j)
  695. 155   continue
  696. c      write(6,*)' continue 155'
  697.       do 160 i=2,mx
  698.          j=i-1
  699.          t=acof5(i)
  700.          call put(t,a,mx,ia,ja,i,j)
  701. 160   continue
  702. c      write(6,*)' continue 160'
  703.        do 165 i=1,mx
  704.         j=i
  705.         t=acof0(i)
  706.        call put(t,a,mx,ia,ja,i,j)
  707. 165   continue
  708. c      write(6,*)' continue 165'
  709.        do 170 i=1,mx-1
  710.           j=i+1
  711.           t=acof6(i)
  712.           call put(t,a,mx,ia,ja,i,j)
  713. 170   continue
  714. c      write(6,*)' continue 170'
  715.        do 175 i=1,mx-bwi
  716.           j=i+bwi
  717.           t=acof2(i)
  718.           call put(t,a,mx,ia,ja,i,j)
  719. 175   continue
  720. c      write(6,*)' continue 175'
  721.        do 180 i=1,mx-bwo
  722.           j=i+bwo
  723.           t=acof4(i)
  724.           call put(t,a,mx,ia,ja,i,j)
  725. 180   continue
  726. c      write(6,*)' continue 180'
  727. c   load zeros for fill-in stripes
  728.        if(iflo .eq. 0) go to 195
  729.        do 192 k = 1,iflo
  730.        do 185 i=1+bwo-k,mx
  731.           j=i-bwo+k
  732.           t=0.0e0
  733.           call put(t,a,mx,ia,ja,i,j)
  734. 185   continue
  735. c      write(6,*)' continue 185'
  736.       do 190 i=1,mx-bwo+k
  737.          j=i+bwo-k
  738.          t=0.0e0
  739.          call put(t,a,mx,ia,ja,i,j)
  740. 190   continue
  741. 192   continue
  742. c      write(6,*)' continue 190'
  743. 195   continue
  744. c      write(6,*)' continue 195'
  745.        if(ifli .eq. 0) go to 210
  746.        do 208 k = 1,ifli
  747.        do 200 i=1+bwi-k,mx
  748.        j=i-bwi+k
  749.        t=0.0e0
  750.        call put(t,a,mx,ia,ja,i,j)
  751. 200   continue
  752. c      write(6,*)' continue 200'
  753.        do 205 i=1,mx-bwi+k
  754.           j=i+bwi-k
  755.           t=0.0e0
  756.           call put(t,a,mx,ia,ja,i,j)
  757. 205   continue
  758. 208   continue
  759. c      write(6,*)' continue 205'
  760. 210   continue
  761. c      write(6,*)' continue 210'
  762.        if( iflm .eq. 0 ) go to 219
  763.        do 217 k = 1,iflm
  764.           do 212 i = 1+bwi+k,mx
  765.              j = i - bwi - k
  766.              call put(0.0e0,a,mx,ia,ja,i,j)
  767.   212     continue
  768.           do 213 i = 1,mx-bwi-k
  769.              j = i + bwi + k
  770.              call put(0.0e0,a,mx,ia,ja,i,j)
  771.   213     continue
  772.   217 continue
  773.   219 continue
  774. c   have now loaded the a,ia,ja arrays
  775. c      write(6,*) 'formula,actual',nonzt,ia(mx+1)
  776.       go to 215
  777. 220  write(6,*) 'ifli or iflo too large'
  778. 215  continue
  779. c      write(6,*)' continue 215'
  780.       return
  781.       end
  782.       subroutine prbtyp(ineum5,ineum6,ising,imx,imy,imz,iflg)
  783.        integer ineum5,ineum6,ising,imx,imy,imz,iflg
  784.        integer n5,n6,isg,ix,iy,iz
  785. c  ineum5=0,dir on bot; =1,neuman on bot
  786. c  ineum6=0,dir on top; =1,neuman on top
  787. c  ising =0,regular; =1 singular if neuman on top & bot
  788. c  imx = # mesh cells in x dir
  789. c  imy = # mesh cells in y dir
  790. c  imz = # mesh cells in z dir
  791. c  iflg =0 sets local values;=1 returns local values
  792. c
  793. c
  794.       if(iflg .eq. 0) go to 10
  795. c      write(6,*)' in prbtyp ix,iy,iz recall',ix,iy,iz
  796.       ineum5=n5
  797.       ineum6=n6
  798.       ising=isg
  799.       imx=ix
  800.       imy=iy
  801.       imz=iz
  802. c      write(6,*)' in prbtyp recall imx,imy,imz',imx,imy,imz
  803.       go to 20
  804. 10   continue
  805. c      write(6,*)' continue #'
  806. c      write(6,*)' in prbtyp init imx,imy,imz',imx,imy,imz
  807.       n5=ineum5
  808.       n6=ineum6
  809.       isg=ising
  810.       ix=imx
  811.       iy=imy
  812.       iz=imz
  813. c      write(6,*)   ' *********** problem type *************'
  814. c      if( ineum5 .eq. 0 ) then
  815. c         write(6,*)' *****       dir on bottom        *****'
  816. c      else
  817. c         write(6,*)' *****     neuman on bottom       *****'
  818. c      endif
  819. c      if( ineum6 .eq. 0 ) then
  820. c         write(6,*)' *****         dir on top         *****'
  821. c      else
  822. c         write(6,*)' *****      neuman on top         *****'
  823. c      endif
  824. c      if( ising .eq. 0 ) then
  825. c         write(6,*)' *****         regular            *****'
  826. c      else
  827. c         write(6,*)' ***** singular if neuman on top and bottom *****'
  828. c      endif
  829. c      write(6,*)   ' ***** mesh cells in x dir',imx,'     *****'
  830. c      write(6,*)   ' ***** mesh cells in y dir',imy,'     *****'
  831. c      write(6,*)   ' ***** mesh cells in z dir',imz,'     *****'
  832. 20   continue
  833. c      write(6,*)' continue #'
  834.       return
  835.       end
  836.       subroutine iccglu(a,n,ia,ja,af,b,x,r,p,s,tol,maxits,its,job,info)
  837. c
  838.       integer n,ia(1),ja(1),maxits,its,job,info
  839.       real a(1),af(1),x(1),r(1),p(1),s(1),b(1),tol
  840. c
  841. c     this routine performs preconditioned conjugate gradient on a
  842. c     sparse matrix. the preconditioner is an incomplete lu of
  843. c     the matrix.
  844. c
  845. c     on entry:
  846. c
  847. c        a  real()
  848. c           contains the elements of the matrix.
  849. c
  850. c        n  integer
  851. c           is the order of the matrix.
  852. c
  853. c        ia integer(n+1)
  854. c           contains pointers to the start of the rows in the arrays
  855. c           a and ja.
  856. c
  857. c        ja integer()
  858. c           contains the column location of the corresponding elements
  859. c           in the array a.
  860. c
  861. c        b real (n)
  862. c           contains the right hand side.
  863. c
  864. c        x real (n)
  865. c           contains an estimate of the solution, the closer it
  866. c           is to the true solution the faster tthe method will
  867. c           converge.
  868. c
  869. c        tol real
  870. c           is the accuracy desired in the solution.
  871. c
  872. c        maxits integer
  873. c           is the maximun number of iterations to be taken
  874. c           by the routine.
  875. c
  876. c        job integer
  877. c           is a flag to signal if incomplete factorization
  878. c           aready exits in array af.
  879. c           job = 0  perform incomplete factorization
  880. c           job = 1  skip incomplete factorization
  881. c
  882. c     on output
  883. c
  884. c        af real ()
  885. c           contains the incomplete factorization of the matrix
  886. c           contained in the array a.
  887. c
  888. c        x real (n)
  889. c          contains the solution.
  890. c
  891. c        r,p,s real (n)
  892. c          these are scratch work arrays.
  893. c
  894. c        its integer
  895. c          contains the number of iterations need to converge.
  896. c
  897. c        info integer
  898. c          signals if normal termination.
  899. c          info = 0 method converged in its iterations
  900. c          info = 1 method converged, but exit occurred because
  901. c                   residual norm was less than sqrt(rtxmin).
  902. c          info = -999 method didnot converge in maxits iterations.
  903. c
  904. c
  905. c     the algorithm has the following form.
  906. c
  907. c        form incomplete factors l and u
  908. c        x(0) <- initial estiate
  909. c        r(0) <- b - a*x(0)
  910. c        r(0) <- trans(a)*invtrans(l)*invtrans(u)*inv(u)*inv(l)*r(0)
  911. c        p(0) <- r(0)
  912. c        i    <- 0
  913. c        while r(i) > tol do
  914. c           s      <- inv(u)*inv(l)*a*p(i)
  915. c           a(i)   <- trans(r(i))*r(i)/(trans(s)*s)
  916. c           x(i+1) <- x(i) + a(i)*p(i)
  917. c           r(i+1) <- r(i) - a(i)*trans(a)*invtrans(l)*invtrans(u)*s
  918. c           b(i)   <- trans(r(i+1))*r(i+1)/(trans(r(i))*r(i))
  919. c           p(i+1) <- r(i+1) + b(i)*p(i)
  920. c           i      <- i + 1
  921. c        end
  922. c
  923.       real ai,bi,rowold,rownew,xnrm,anrm
  924.       real sdot
  925.       real rtxmax,rtxmin
  926.       common /gear14/ rtxmax,rtxmin
  927.       data rtxmin/1.0e-16/
  928.       info = 0
  929.       anrm = abs(a(isamax(ia(n+1)-1,a,1)))
  930. c
  931. c     form incomplete factors l and u
  932. c
  933.       if( job .ne. 0 ) go to 5
  934.          call scopy(ia(n+1)-1,a,1,af,1)
  935.          call lu(af,n,ia,ja)
  936.     5 continue
  937. c
  938. c     r(0) <- b - a*x(0)
  939. c
  940.       call cgres(a,n,ia,ja,x,b,r)
  941. c
  942. c     r(0) <- trans(a)*invtrans(l)*invtrans(u)*inv(u)*inv(l)*r(0)
  943. c
  944. c     inv(u)*inv(l)*r(0)
  945. c
  946.       call scopy(n,r,1,s,1)
  947.       call ssol(af,n,ia,ja,s,1)
  948.       call ssol(af,n,ia,ja,s,2)
  949. c
  950. c     invtrans(l)*invtrans(u)*above
  951. c
  952.       call ssol(af,n,ia,ja,s,-2)
  953.       call ssol(af,n,ia,ja,s,-1)
  954. c
  955. c     trans(a)*above
  956. c
  957.       call mmult(a,n,ia,ja,r,s,-1)
  958. c
  959. c     p(0) <- r(0)
  960. c
  961.       call scopy(n,r,1,p,1)
  962.       rowold = sdot(n,r,1,r,1)
  963.       i = 0
  964. c
  965. c     while r(i) > tol do
  966. c
  967.       ai = 1.0d0
  968.    10 continue
  969.       xnrm = abs(x(isamax(n,x,1)))
  970. cc    write(6,*) ' iter residual xnrm ai',i,sqrt(rowold)/(anrm*xnrm),
  971. cc   $            xnrm,ai
  972.       if( sqrt(rowold) .le. tol*(anrm*xnrm) ) go to 12
  973. cc    if (rowold .le. rtxmin) go to 25
  974.    13 continue
  975. c
  976. c        s      <- inv(u)*inv(l)*a*p(i)
  977. c
  978.          call mmult(a,n,ia,ja,s,p,1)
  979.          call ssol(af,n,ia,ja,s,1)
  980.          call ssol(af,n,ia,ja,s,2)
  981. c
  982. c        a(i)   <- trans(r(i))*r(i)/(trans(s)*s)
  983. c
  984.          ai = rowold/sdot(n,s,1,s,1)
  985. c
  986. c        x(i+1) <- x(i) + a(i)*p(i)
  987. c
  988.          call saxpy(n,ai,p,1,x,1)
  989. c
  990. c
  991. c        r(i+1) <- r(i) - a(i)*trans(a)*invtrans(l)*invtrans(u)*s
  992. c
  993.          call ssol(af,n,ia,ja,s,-2)
  994.          call ssol(af,n,ia,ja,s,-1)
  995.          call mmult(a,n,ia,ja,b,s,-1)
  996.          call saxpy(n,-ai,b,1,r,1)
  997. c
  998. c        b(i)   <- trans(r(i+1))*r(i+1)/(trans(r(i))*r(i))
  999. c
  1000.          rownew = sdot(n,r,1,r,1)
  1001.          bi = rownew/rowold
  1002. c
  1003. c        p(i+1) <- r(i+1) + b(i)*p(i)
  1004. c
  1005.          call saxpy2(n,bi,p,1,r,1)
  1006.          rowold = rownew
  1007. c
  1008. c        i      <- i + 1
  1009. c
  1010.          i = i + 1
  1011.          if( i .gt. maxits ) go to 20
  1012.          go to 10
  1013.    12 continue
  1014.    15 continue
  1015.       its = i
  1016.       return
  1017.    20 continue
  1018.       info = -999
  1019.       its = maxits
  1020.       return
  1021. c  25 continue
  1022. c     info = 1
  1023. c     its = i
  1024. c     return
  1025.       end
  1026.       subroutine axpy(a,n,ia,ja,i,js,je,t,y)
  1027. c
  1028.       integer n,ia(1),ja(1),i,js,je
  1029.       real a(1),y(1)
  1030.       real t
  1031. c
  1032. c     this routine computes an axpy for a row of a sparse matrix
  1033. c     with a vector.
  1034. c     an axpy is a multiple of a row of the matrix is added to the
  1035. c     vector y.
  1036. c
  1037.       is = ia(i)
  1038.       ie = ia(i+1) - 1
  1039.       do 10 ir = is,ie
  1040.          j = ja(ir)
  1041.          if( j .gt. je ) go to 20
  1042.          if( j .lt. js ) go to 10
  1043.          y(j) = y(j) + t*a(ir)
  1044.    10 continue
  1045.    20 continue
  1046.       return
  1047.       end
  1048.       subroutine saxpy2(n,da,dx,incx,dy,incy)
  1049. c
  1050. c     constant times a vector plus a vector.
  1051. c     uses unrolled loops for increments equal to one.
  1052. c     jack dongarra, linpack, 3/11/78.
  1053. c
  1054.       real dx(1),dy(1),da
  1055.       integer i,incx,incy,m,mp1,n  
  1056. c
  1057.       if(n.le.0)return
  1058.       if (da .eq. 0.0e0) return
  1059.       if(incx.eq.1.and.incy.eq.1)go to 20
  1060. c
  1061. c        code for unequal increments or equal increments
  1062. c          not equal to 1
  1063. c
  1064.       ix = 1
  1065.       iy = 1
  1066.       if(incx.lt.0)ix = (-n+1)*incx + 1
  1067.       if(incy.lt.0)iy = (-n+1)*incy + 1
  1068.       do 10 i = 1,n
  1069.         dx(iy) = dy(iy) + da*dx(ix)
  1070.         ix = ix + incx
  1071.         iy = iy + incy
  1072.    10 continue
  1073.       return
  1074. c
  1075. c        code for both increments equal to 1
  1076. c
  1077. c
  1078. c        clean-up loop
  1079. c
  1080.    20 m = mod(n,4)
  1081.       if( m .eq. 0 ) go to 40
  1082.       do 30 i = 1,m
  1083.         dx(i) = dy(i) + da*dx(i)
  1084.    30 continue
  1085.       if( n .lt. 4 ) return
  1086.    40 mp1 = m + 1
  1087.       do 50 i = mp1,n,4
  1088.         dx(i) = dy(i) + da*dx(i)
  1089.         dx(i + 1) = dy(i + 1) + da*dx(i + 1)
  1090.         dx(i + 2) = dy(i + 2) + da*dx(i + 2)
  1091.         dx(i + 3) = dy(i + 3) + da*dx(i + 3)
  1092.    50 continue
  1093.       return
  1094.       end
  1095.       real function dot(a,n,ia,ja,i,js,je,b)
  1096. c
  1097.       integer n,ia(1),ja(1),i,js,je
  1098.       real a(1),b(1)
  1099.       real t
  1100. c
  1101. c     this routine computes an inner product for a row of a sparse matri
  1102. c     with a vector.
  1103. c
  1104.       t = 0.0e0
  1105.       is = ia(i)
  1106.       ie = ia(i+1) - 1
  1107.       do 10 ir = is,ie
  1108.          j = ja(ir)
  1109.          if( j .gt. je ) go to 20
  1110.          if( j .lt. js ) go to 10
  1111.          t = t + a(ir)*b(j)
  1112.    10 continue
  1113.    20 continue
  1114.       dot = t
  1115.       return
  1116.       end
  1117.       subroutine inits(a,n,ia,ja)
  1118. c
  1119.       integer n,ia(1),ja(1)
  1120.       real a(1)
  1121. c
  1122. c     this routine initializes storage for the sparse
  1123. c     matrix arrays.
  1124. c     note: the matrix is initialized to have zeroes
  1125. c     on the diagonal.
  1126. c
  1127.       do 10 i = 1,n
  1128.          a(i) = 0.0e0
  1129.          ja(i) = i
  1130.          ia(i) = i
  1131.    10 continue
  1132.       ia(n+1) = n+1
  1133.       return
  1134.       end
  1135.       subroutine insert(t,a,n,ia,ja,i,j,k)
  1136. c
  1137.       integer n,ia(1),ja(1),i,j,k
  1138.       integer ip1,np1
  1139.       real t,a(1)
  1140. c
  1141. c     this routine rearranges the elements in arrays a and ja
  1142. c     and updates array ia for the new element.
  1143. c
  1144. cc    write(6,1000)i,j,ia(i),ia(i+1),t
  1145. 1000  format('  *** from insert i,j,ia(i),ia(i+1),t ',4i5,1x,e15.8)
  1146.       l1 = k
  1147.       l2 = ia(n+1) - 1
  1148.       do 10 lb = l1,l2
  1149.          l = l2 - lb + l1
  1150.          a(l+1) = a(l)
  1151.          ja(l+1) = ja(l)
  1152.    10 continue
  1153.       a(k) = t
  1154.       ja(k) = j
  1155.       ip1 = i + 1
  1156.       np1 = n + 1
  1157.       do 20 l = ip1,np1
  1158.          ia(l) = ia(l) + 1
  1159.    20 continue
  1160.       return
  1161.       end
  1162.       logical function locate(a,n,ia,ja,i,j,k)
  1163. c
  1164.       integer n,ia(1),ja(1),i,j
  1165.       real a(1)
  1166. c
  1167. c     this routine will locate the i,j-th element in the
  1168. c     sparse matrix structure.
  1169. c
  1170.       is = ia(i)
  1171.       ie = ia(i+1) - 1
  1172. c
  1173. c     row i is from is to ie in array a.
  1174. c
  1175.       do 10 l = is,ie
  1176.          if( j .gt. ja(l) ) go to 10
  1177.          if( j .ne. ja(l) ) go to 5
  1178.             locate = .true.
  1179.             k = l
  1180.             go to 20
  1181.     5    continue
  1182.          if( j .ge. ja(l) ) go to 10
  1183.             locate = .false.
  1184.             k = 0
  1185.          go to 20
  1186.    10 continue
  1187. c
  1188. c     get here if should be at the end of a row.
  1189. c
  1190.       locate = .false.
  1191.       k = 0
  1192.    20 continue
  1193.       return
  1194.       end
  1195.       subroutine lu(a,n,ia,ja)
  1196. c
  1197.       logical locate
  1198.       integer n,ia(1),ja(1)
  1199.       integer ikp1,kp1
  1200.       real a(1)
  1201. c
  1202. c     this subroutine does incomplete gaussian elimenation
  1203. c     on a sparse matrix. the matrix is stored in a sparse
  1204. c     data structure.
  1205. c     note: no pivoting is done
  1206. c           and the factorization is incomplete,
  1207. c           i.e., only where there exists a storage location
  1208. c           will the operation take place.
  1209. c
  1210.       do 40 k = 1,n
  1211.          if( .not. locate(a,n,ia,ja,k,k,l2) ) go to 50
  1212.          if( a(l2) .eq. 0.0e0 ) go to 50
  1213.          kp1 = k + 1
  1214.          do 30 i = kp1,n
  1215.             if( .not. locate(a,n,ia,ja,i,k,ik) ) go to 25
  1216.                is = ik
  1217.                ie = ia(i+1) - 1
  1218.                kj = l2
  1219.                ke = ia(k+1) - 1
  1220.                a(ik) = a(ik)/a(kj)
  1221.                if( kj .eq. ke ) go to 30
  1222.                kj = kj + 1
  1223.                ikp1 = ik + 1
  1224.                do 20 j = ikp1,ie
  1225.    10             continue
  1226.                      if( kj .gt. ke ) go to 30
  1227.                      if( ja(kj) .ge. ja(j) ) go to 15
  1228.                         kj = kj + 1
  1229.                         go to 10
  1230.    15                continue
  1231.                   if( ja(kj) .gt. ja(j) ) go to 20
  1232.                   a(j) = a(j) - a(ik)*a(kj)
  1233.    20          continue
  1234.    25       continue
  1235.    30    continue
  1236.    40 continue
  1237.       return
  1238.    50 continue
  1239. cc    write(6,*)' value of k and a(k,k)',k,a(l2)
  1240. cc    write(6,*)' error zero on diagonal'
  1241. cc    write(6,*)' matrix probably specified incorrectly or'
  1242. cc    write(6,*)' incomplete factorization produces a singular matrix'
  1243.       return
  1244.       end
  1245.       subroutine mmult(a,n,ia,ja,b,x,job)
  1246. c
  1247.       integer n,ia(1),ja(1),job
  1248.       real a(1),b(1),x(1)
  1249. c
  1250. c     this routine performs matrix vector multiple
  1251. c     for a sparse matrix structure
  1252. c
  1253. c     job has the following input meanings:
  1254. c         job = 1  matrix vector multiple
  1255. c             = -1 matrix transpose vector multiple
  1256. c             = 2  unit lower matrix vector multiple
  1257. c             = -2 unit lower matrix transpose vector multiple
  1258. c             = 3  upper matrix vector multiple
  1259. c             = -3 upper matrix transpose vector multiple
  1260.       real dot
  1261. c
  1262. c     a*x
  1263. c
  1264.       if( job .ne. 1 ) go to 15
  1265.          do 10 i = 1,n
  1266.             b(i) = dot(a,n,ia,ja,i,1,n,x)
  1267.    10    continue
  1268. c
  1269. c     trans(a)*x
  1270. c
  1271.    15 continue
  1272.       if( job .ne. -1 ) go to 35
  1273.          do 20 i = 1,n
  1274.             b(i) = 0.0e0
  1275.    20    continue
  1276.          do 30 i = 1,n
  1277.             call axpy(a,n,ia,ja,i,1,n,x(i),b)
  1278.    30    continue
  1279. c
  1280. c     l*x   when l is unit lower
  1281. c
  1282.    35 continue
  1283.       if( job .ne. 2 ) go to 45
  1284.          do 40 i = 1,n
  1285.             b(i) = x(i) + dot(a,n,ia,ja,i,1,i-1,x)
  1286.    40    continue
  1287. c
  1288. c     trans(l)*x   when l is unit lower
  1289. c
  1290.    45 continue
  1291.       if( job .ne. -2 ) go to 55
  1292.          do 49 i = 1,n
  1293.             b(i) = x(i)
  1294.    49    continue
  1295.          do 50 i = 1,n
  1296.             call axpy(a,n,ia,ja,i,i,n,x(i),b)
  1297.    50    continue
  1298. c
  1299. c     u*x
  1300. c
  1301.    55 continue
  1302.       if( job .ne. 3 ) go to 65
  1303.          do 60 i = 1,n
  1304.             b(i) = dot(a,n,ia,ja,i,i,n,x)
  1305.    60    continue
  1306. c
  1307. c     trans(u)*x
  1308. c
  1309.    65 continue
  1310.       if( job .ne. -3 ) go to 85
  1311.          do 70 i = 1,n
  1312.             b(i) = 0.0e0
  1313.    70    continue
  1314.          do 80 i = 1,n
  1315.             call axpy(a,n,ia,ja,i,1,i,x(i),b)
  1316.    80    continue
  1317.    85 continue
  1318.       return
  1319.       end
  1320.       subroutine put(t,a,n,ia,ja,i,j)
  1321. c
  1322.       integer n,ia(1),ja(1),i,j
  1323.       real t,a(1)
  1324. c
  1325. c     this routine will insert an element into the sparse matrix
  1326. c     structure.
  1327. c
  1328.       is = ia(i)
  1329.       ie = ia(i+1) - 1
  1330. cc    write(6,100)i,j,ia(i),ia(i+1)
  1331. 100   format('  *** from put i,j,ia(i),ia(i+1) ',4i7)
  1332. c
  1333. c     row i is from is to ie in array a.
  1334. c
  1335.       do 10 k = is,ie
  1336.          if( j .gt. ja(k) ) go to 10
  1337.          if( j .ne. ja(k) ) go to 5
  1338.             a(k) = t
  1339.             go to 20
  1340.     5    continue
  1341.          if( j .ge. ja(k) ) go to 12
  1342.             call insert(t,a,n,ia,ja,i,j,k)
  1343.             go to 20
  1344.    12    continue
  1345.    10 continue
  1346. c
  1347. c     get here if should be at the end of a row.
  1348. c
  1349.       k = ie + 1
  1350.       call insert(t,a,n,ia,ja,i,j,k)
  1351.       go to 30
  1352.    20 continue
  1353.    30 continue
  1354.       return
  1355.       end
  1356.       subroutine cgres(a,n,ia,ja,x,b,r)
  1357. c
  1358.       integer n,ia(1),ja(1)
  1359.       real a(1),x(1),b(1),r(1)
  1360. c
  1361. c     this routine computes a residual for a*x=b where
  1362. c     a is in a sparse structure
  1363. c
  1364.       real dot
  1365.       do 10 i = 1,n
  1366.          r(i) = b(i) - dot(a,n,ia,ja,i,1,n,x)
  1367.    10 continue
  1368.       return
  1369.       end
  1370.       subroutine ssol(a,n,ia,ja,b,job)
  1371. c
  1372.       integer n,ia(1),ja(1),job
  1373.       real a(1),b(1)
  1374. c
  1375. c     this routine solves a system of equations based on a sparse
  1376. c     matrix date structure.
  1377. c     the array b contains the right hand side on input
  1378. c         and on output has the solution
  1379. c
  1380. c     job has the value 1 if l*x = b is to be solved.
  1381. c     job has the value -1 if trans(l)*x = b is to be solved.
  1382. c     job has the value 2 if u*x = b is to be solved.
  1383. c     job has the value -2 if trans(u)*x = b is to be solved.
  1384. c
  1385.       logical locate
  1386.       real t
  1387.       real dot
  1388. c
  1389. c     job = 1  solve  l*x = b
  1390. c
  1391.       if( job .ne. 1 ) go to 15
  1392. c
  1393. c        solve l*y=b
  1394. c
  1395.          do 10 i = 2,n
  1396.             b(i) = b(i) - dot(a,n,ia,ja,i,1,i-1,b)
  1397.    10    continue
  1398.    15 continue
  1399.       if( job .ne. 2 ) go to 25
  1400. c
  1401. c        solve u*x=y
  1402. c
  1403.          do 20 ib = 1,n
  1404.             i = n - ib + 1
  1405.             t = dot(a,n,ia,ja,i,i+1,n,b)
  1406.             if( .not. locate(a,n,ia,ja,i,i,k) ) go to 30
  1407.             b(i) = (b(i) - t)/a(k)
  1408.    20    continue
  1409. c
  1410. c     job = -2  solve  trans(u)*x = b
  1411. c
  1412.    25 continue
  1413.       if( job .ne. -2 ) go to 35
  1414. c
  1415. c        solve trans(u)*y=b
  1416. c
  1417.          do 21 i = 1,n
  1418.             if( .not. locate(a,n,ia,ja,i,i,k) ) go to 30
  1419.             b(i) = b(i)/a(k)
  1420.             call axpy(a,n,ia,ja,i,i+1,n,-b(i),b)
  1421.    21    continue
  1422. c
  1423. c        solve trans(l)*x=y
  1424. c
  1425.    35 continue
  1426.       if( job .ne. -1 ) go to 45
  1427.          do 22 ib = 2,n
  1428.             i = n - ib + 2
  1429.             call axpy(a,n,ia,ja,i,1,i-1,-b(i),b)
  1430.    22    continue
  1431.    45 continue
  1432.       return
  1433.    30 continue
  1434. cc    write(6,*)' error no diagonal element: from solve'
  1435.       return
  1436.       end
  1437.       subroutine saxpy(n,sa,sx,incx,sy,incy)
  1438. c
  1439. c     constant times a vector plus a vector.
  1440. c     uses unrolled loop for increments equal to one.
  1441. c     jack dongarra, linpack, 3/11/78.
  1442. c
  1443.       real sx(1),sy(1),sa
  1444.       integer i,incx,incy,ix,iy,m,mp1,n
  1445. c
  1446.       if(n.le.0)return
  1447.       if (sa .eq. 0.0) return
  1448.       if(incx.eq.1.and.incy.eq.1)go to 20
  1449. c
  1450. c        code for unequal increments or equal increments
  1451. c          not equal to 1
  1452. c
  1453.       ix = 1
  1454.       iy = 1
  1455.       if(incx.lt.0)ix = (-n+1)*incx + 1
  1456.       if(incy.lt.0)iy = (-n+1)*incy + 1
  1457.       do 10 i = 1,n
  1458.         sy(iy) = sy(iy) + sa*sx(ix)
  1459.         ix = ix + incx
  1460.         iy = iy + incy
  1461.    10 continue
  1462.       return
  1463. c
  1464. c        code for both increments equal to 1
  1465. c
  1466. c
  1467. c        clean-up loop
  1468. c
  1469.    20 m = mod(n,4)
  1470.       if( m .eq. 0 ) go to 40
  1471.       do 30 i = 1,m
  1472.         sy(i) = sy(i) + sa*sx(i)
  1473.    30 continue
  1474.       if( n .lt. 4 ) return
  1475.    40 mp1 = m + 1
  1476.       do 50 i = mp1,n,4
  1477.         sy(i) = sy(i) + sa*sx(i)
  1478.         sy(i + 1) = sy(i + 1) + sa*sx(i + 1)
  1479.         sy(i + 2) = sy(i + 2) + sa*sx(i + 2)
  1480.         sy(i + 3) = sy(i + 3) + sa*sx(i + 3)
  1481.    50 continue
  1482.       return
  1483.       end
  1484.       subroutine scopy(n,sx,incx,sy,incy)
  1485. c
  1486. c     copies a vector, x, to a vector, y.
  1487. c     uses unrolled loops for increments equal to 1.
  1488. c     jack dongarra, linpack, 3/11/78.
  1489. c
  1490.       real sx(1),sy(1)
  1491.       integer i,incx,incy,ix,iy,m,mp1,n
  1492. c
  1493.       if(n.le.0)return
  1494.       if(incx.eq.1.and.incy.eq.1)go to 20
  1495. c
  1496. c        code for unequal increments or equal increments
  1497. c          not equal to 1
  1498. c
  1499.       ix = 1
  1500.       iy = 1
  1501.       if(incx.lt.0)ix = (-n+1)*incx + 1
  1502.       if(incy.lt.0)iy = (-n+1)*incy + 1
  1503.       do 10 i = 1,n
  1504.         sy(iy) = sx(ix)
  1505.         ix = ix + incx
  1506.         iy = iy + incy
  1507.    10 continue
  1508.       return
  1509. c
  1510. c        code for both increments equal to 1
  1511. c
  1512. c
  1513. c        clean-up loop
  1514. c
  1515.    20 m = mod(n,7)
  1516.       if( m .eq. 0 ) go to 40
  1517.       do 30 i = 1,m
  1518.         sy(i) = sx(i)
  1519.    30 continue
  1520.       if( n .lt. 7 ) return
  1521.    40 mp1 = m + 1
  1522.       do 50 i = mp1,n,7
  1523.         sy(i) = sx(i)
  1524.         sy(i + 1) = sx(i + 1)
  1525.         sy(i + 2) = sx(i + 2)
  1526.         sy(i + 3) = sx(i + 3)
  1527.         sy(i + 4) = sx(i + 4)
  1528.         sy(i + 5) = sx(i + 5)
  1529.         sy(i + 6) = sx(i + 6)
  1530.    50 continue
  1531.       return
  1532.       end
  1533.       real function sdot(n,sx,incx,sy,incy)
  1534. c
  1535. c     forms the dot product of two vectors.
  1536. c     uses unrolled loops for increments equal to one.
  1537. c     jack dongarra, linpack, 3/11/78.
  1538. c
  1539.       real sx(1),sy(1),stemp
  1540.       integer i,incx,incy,ix,iy,m,mp1,n
  1541. c
  1542.       stemp = 0.0e0
  1543.       sdot = 0.0e0
  1544.       if(n.le.0)return
  1545.       if(incx.eq.1.and.incy.eq.1)go to 20
  1546. c
  1547. c        code for unequal increments or equal increments
  1548. c          not equal to 1
  1549. c
  1550.       ix = 1
  1551.       iy = 1
  1552.       if(incx.lt.0)ix = (-n+1)*incx + 1
  1553.       if(incy.lt.0)iy = (-n+1)*incy + 1
  1554.       do 10 i = 1,n
  1555.         stemp = stemp + sx(ix)*sy(iy)
  1556.         ix = ix + incx
  1557.         iy = iy + incy
  1558.    10 continue
  1559.       sdot = stemp
  1560.       return
  1561. c
  1562. c        code for both increments equal to 1
  1563. c
  1564. c
  1565. c        clean-up loop
  1566. c
  1567.    20 m = mod(n,5)
  1568.       if( m .eq. 0 ) go to 40
  1569.       do 30 i = 1,m
  1570.         stemp = stemp + sx(i)*sy(i)
  1571.    30 continue
  1572.       if( n .lt. 5 ) go to 60
  1573.    40 mp1 = m + 1
  1574.       do 50 i = mp1,n,5
  1575.         stemp = stemp + sx(i)*sy(i) + sx(i + 1)*sy(i + 1) +
  1576.      *   sx(i + 2)*sy(i + 2) + sx(i + 3)*sy(i + 3) + sx(i + 4)*sy(i + 4)
  1577.    50 continue
  1578.    60 sdot = stemp
  1579.       return
  1580.       end
  1581.       integer function isamax(n,sx,incx)
  1582. c
  1583. c     finds the index of element having max. absolute value.
  1584. c     jack dongarra, linpack, 3/11/78.
  1585. c
  1586.       real sx(1),smax
  1587.       integer i,incx,ix,n
  1588. c
  1589.       isamax = 0
  1590.       if( n .lt. 1 ) return
  1591.       isamax = 1
  1592.       if(n.eq.1)return
  1593.       if(incx.eq.1)go to 20
  1594. c
  1595. c        code for increment not equal to 1
  1596. c
  1597.       ix = 1
  1598.       smax = abs(sx(1))
  1599.       ix = ix + incx
  1600.       do 10 i = 2,n
  1601.          if(abs(sx(ix)).le.smax) go to 5
  1602.          isamax = i
  1603.          smax = abs(sx(ix))
  1604.     5    ix = ix + incx
  1605.    10 continue
  1606.       return
  1607. c
  1608. c        code for increment equal to 1
  1609. c
  1610.    20 smax = abs(sx(1))
  1611.       do 30 i = 2,n
  1612.          if(abs(sx(i)).le.smax) go to 30
  1613.          isamax = i
  1614.          smax = abs(sx(i))
  1615.    30 continue
  1616.       return
  1617.       end
复制代码
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

QQ|小黑屋|Archiver|手机版|联系我们|声振论坛

GMT+8, 2024-11-25 14:22 , Processed in 0.099633 second(s), 17 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表