00001 subroutine bicgstab_no_s(A,b,x,n,tol,mainloop,k)
00002 implicit none
00003 integer n,i,j,k,mainloop
00004 real(8) A(n,n),b(n),x(n),res(n)
00005 real(8) rhat(n),p(n),v(n),t(n)
00006 real(8) alpha,beta,omega,rho,rhonew,norm_value,aux,res_one
00007 real(8) tol
00008 integer,parameter :: display=100
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 v=0.d0
00025 p=0.d0
00026 t=0.d0
00027
00028 res=0.d0
00029 rhat=0.d0
00030
00031
00032
00033
00034
00035
00036 call MatVecMult(A,x,res,n)
00037
00038 res=b-res
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 rhat=res
00049
00050
00051 rho=1.d0
00052 alpha=1.d0
00053 omega=1.d0
00054
00055
00056
00057
00058 Open (111,File='linearResidual.dat',Status='unknown')
00059 norm_value=dsqrt(dot_product(res,res))
00060 write(111,'(E30.20,1X)')norm_value
00061
00062 res_one=norm_value
00063
00064 do i=1,mainloop
00065
00066
00067
00068
00069
00070 rhonew=dot_product(res,rhat)
00071
00072
00073 if (rhonew.eq.0) then
00074 print*,'Method fails: rho=0'
00075 exit
00076 end if
00077
00078 beta=rhonew/rho*alpha/omega
00079
00080
00081
00082 p=res+beta*(p-omega*v)
00083
00084
00085
00086
00087 call MatVecMult(A,p,v,n)
00088
00089
00090
00091
00092 alpha=rhonew/dot_product(v,rhat)
00093
00094
00095
00096
00097 res=res-alpha*v
00098
00099
00100 if (dot_product(res,res).le.epsilon(0.d0)) then
00101
00102 goto 100
00103
00104
00105 end if
00106
00107
00108
00109
00110
00111 call MatVecMult(A,res,t,n)
00112
00113
00114
00115
00116
00117
00118 omega=dot_product(t,res)/dot_product(t,t)
00119
00120 if (omega.eq.0) then
00121 print*,'Method cannot continue:w=0'
00122 exit
00123 end if
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 100 x=x+alpha*p+omega*res
00138
00139
00140
00141
00142
00143
00144 res=res-omega*t
00145
00146
00147
00148
00149 rho=rhonew
00150
00151
00152 norm_value=dsqrt(dot_product(res,res))
00153
00154
00155
00156 write(111,'(E30.20,1X)')norm_value
00157
00158 if (norm_value/res_one.le.tol) then
00159 print*,'Solver converged'
00160 print*,'i=',i ,'norm=',norm_value
00161 return
00162 end if
00163
00164 if (mod(i,display).eq.0) then
00165 print*,'i=',i ,'relative res=',norm_value/res_one
00166 end if
00167
00168 end do
00169
00170
00171 close(111)
00172
00173
00174 end subroutine