clear;close all;clc;
%-----------------------Define the domian and global variables-------------
Lx = 1; Ly = 1;  Nx=128; Ny=128;  Ng=1; 
is=Ng+1; ie=Nx+Ng; js=Ng+1; je=Ny+Ng;  ieu=ie-1; jev=je-1;
dx=Lx/Nx;dy=Ly/Ny;
xh=(-Ng:(Nx+Ng))*dx;
yh=(-Ng:(Ny+Ng))*dy;
x =0.5d0*(xh(2:end)+xh(1:end-1));
y =0.5d0*(yh(2:end)+yh(1:end-1));
xh=xh(2:end);
yh=yh(2:end);
%-------------Phyiscal and material parameters-----------------------------
PDEa=10; PDEb=200; PDEc=0.5; PDEd=1000;
u=zeros(Nx+2*Ng,Ny+2*Ng);v=zeros(Nx+2*Ng,Ny+2*Ng);
u(:,:)=0d0; v(:,:)=1d0;
for i=1:Nx+2*Ng
    for j=1:Ny+2*Ng
        ru=[x(i)/(0.5*Lx)-1, yh(j)/(0.5*Ly)-1]'; rru=[0,1;-1,0]*ru;
        rv=[xh(i)/(0.5*Lx)-1, y(j)/(0.5*Ly)-1]'; rrv=[0,1;-1,0]*rv;
        u(i,j)=2d0*rru(1);
        v(i,j)=2d0*rrv(2);
    end
end
%-----Parameters for fluid and heat transfer-------------------------------
BoundaryValue=[50 80];
for di=1:size(BoundaryValue,1)
BC1=BoundaryValue(di,1); BC2=BoundaryValue(di,2);
T=zeros(Nx+2*Ng,Ny+2*Ng);
Maxit=500; MaxError=1e-4; 
fpc=zeros(Nx+2*Ng,Ny+2*Ng,6);
rho1_BiCG=1d0; rho2_BiCG=1d0; omega_BiCG=1d0; alpha_BiCG=1d0;
r_i=zeros(Nx+2*Ng,Ny+2*Ng);v_i=zeros(Nx+2*Ng,Ny+2*Ng);
p_i=zeros(Nx+2*Ng,Ny+2*Ng);s_i=zeros(Nx+2*Ng,Ny+2*Ng);
t_i=zeros(Nx+2*Ng,Ny+2*Ng);r_0=zeros(Nx+2*Ng,Ny+2*Ng);

    %--------------------Assemble system equations-------------------------
    T(is-1,:)=0;%Tout/2;
    T(ie+1,:)=0;
    T(:,js-1)=0;%Tout/2;
    T(:,je+1)=0;
    d=round(Nx/2);
    
    T(is:is+d-1,js-1)=BC2;
    T(is+d:ie,js-1)=BC1;
    T(is:is+d-1,je+1)=BC1;
    T(is+d:ie,je+1)=BC2;
      
	for j=js:je; for i=is:ie
		fpc(i,j,1)=PDEa/dx^2-PDEb*u(i,j)/2d0/dx;
		fpc(i,j,2)=PDEa/dy^2-PDEb*v(i,j)/2d0/dy;
		fpc(i,j,4)=PDEa/dx^2+PDEb*u(i-1,j)/2d0/dx;
		fpc(i,j,5)=PDEa/dy^2+PDEb*v(i,j-1)/2d0/dy;
		fpc(i,j,3)=-2d0*PDEa/dx^2-2d0*PDEa/dy^2-...
                   PDEb*u(i,j)/2d0/dx+PDEb*u(i-1,j)/2d0/dx-PDEb*v(i,j)/2d0/dy+PDEb*v(i,j-1)/2d0/dy-PDEc;
        fpc(i,j,3)=-fpc(i,j,3);
		fpc(i,j,6)=PDEd;
        fpc(i,j,1:6)=fpc(i,j,1:6)/fpc(i,j,3);
	end; end
     %---------------------------------------------------------------------   
%==================Bi-CGSTAB solver===================================================================
	%--------------Initial condition for biconjugate gradient stabilized method-----------------------
	rho1_BiCG=1d0; rho2_BiCG=1d0; omega_BiCG=1d0; alpha_BiCG=1d0;
	r_i(:,:)=0;   v_i(:,:)=0;	p_i(:,:)=0;   s_i(:,:)=0;  t_i(:,:)=0;	r_0(:,:)=0;    
	for it=1:Maxit
		%--------------------------Bi-conjugate stabilized iteration---------------------------------------
		%-----------------------1: residual vector r_i=s-w_i*t / B-A*x(i-1) and rho2_BiCG------------------
		rho2_BiCG=0d0;
		for i=is:ie,for j=js:je		
			if(it==1)
				r_i(i,j)=-1d0*T(i,j)+(fpc(i,j,1)*T(i+1,j)+fpc(i,j,2)*T(i,j+1)+...
							fpc(i,j,4)*T(i-1,j)+fpc(i,j,5)*T(i,j-1)+...
							fpc(i,j,6));
				r_0(i,j)=r_i(i,j);
				rho2_BiCG=rho2_BiCG+r_0(i,j)*r_i(i,j);					
			else
				r_i(i,j)=s_i(i,j)-omega_BiCG*t_i(i,j);
				rho2_BiCG=rho2_BiCG+r_0(i,j)*r_i(i,j);
            end
        end;end
		%-----------------------------------------------------------------------------------------
		%------2: beta_BiCG=(rho2_BiCG/rho1_BiCG)*(alpha_BiCG/omega_BiCG);------------------------
		beta_BiCG=(rho2_BiCG/rho1_BiCG)*(alpha_BiCG/omega_BiCG);
		rho1_BiCG=rho2_BiCG;
		%-----------------------------------------------------------------------------------------
		%------3: p_i=r_i+beta*(p_i-1-omega_BiCG*v_i-1)-----------------------------------------
		for i=is:ie,for j=js:je		
			p_i(i,j)=r_i(i,j)+beta_BiCG*(p_i(i,j)-omega_BiCG*v_i(i,j));				
        end; end		
		%-----------------------------------------------------------------------------------------
		%---------4: v_i=A*p_i--------------------------------------------------------------------
		for i=is:ie,for j=js:je			
			v_i(i,j)= 1d0        *p_i(i  ,j)-(fpc(i,j, 1)*p_i(i+1,j  )+fpc(i,j,2)*p_i(i,j+1)+...
						 fpc(i,j,4)*p_i(i-1,j)+ fpc(i,j, 5)*p_i(i  ,j-1));
		end; end	
		%-----------------------------------------------------------------------------------------
		%---------5: alpha_BiCG=rho2_BiCG/(r_0,v_i)-----------------------------------------------
		vbyv_BiCG=0d0;
		for i=is:ie,for j=js:je		
			vbyv_BiCG=vbyv_BiCG+r_0(i,j)*v_i(i,j);
		end; end	
		alpha_BiCG=rho2_BiCG/vbyv_BiCG;
		%-----------------------------------------------------------------------------------------
		%-----------6: s=r_i-alpha_BiCG*v_i-----------------------------------------------------
		for i=is:ie,for j=js:je	
			s_i(i,j)=r_i(i,j)-alpha_BiCG*v_i(i,j);		
		end; end			
		%-----------------------------------------------------------------------------------------
		%------------7: t=A*s---------------------------------------------------------------------
		for i=is:ie,for j=js:je		
			t_i(i,j)= 1d0        *s_i(i  ,j)-(fpc(i,j,1)*s_i(i+1,j  )+fpc(i,j,2)*s_i(i,j+1)+...
						fpc(i,j, 4)*s_i(i-1,j)+ fpc(i,j,5)*s_i(i  ,j-1));
		end; end	
		%-----------------------------------------------------------------------------------------
		%-------------8: omega_BiCG=(t,s)/(t,t)---------------------------------------------------
		vbyv_BiCG=0d0;vbyv1=0d0;
		for i=is:ie,for j=js:je	
			vbyv_BiCG=vbyv_BiCG+s_i(i,j)*t_i(i,j);
			vbyv1=vbyv1+t_i(i,j)*t_i(i,j);
		end; end	
		omega_BiCG=vbyv_BiCG/vbyv1;	
		%-----------------------------------------------------------------------------------------
		%------------9: Update x_i=x_i-1+alpha_BiCG*p_i+omega_BiCG*s------------------------------
		for i=is:ie,for j=js:je	
			T(i,j)=T(i,j)+alpha_BiCG*p_i(i,j)+omega_BiCG*s_i(i,j);
		end; end			
		%-----------------------------------------------------------------------------------------				
		%---------------------------------End of Conjugate Gradient Iteration-----------------------------
		%---------------------------------CHECK FOR CONVERGENCE-------------------------------------------
		if(it>5)
						res=0d0;tmpres=0d0;
				%---------------------------------Check the real error--------------------------------------------
				for i=is:ie,for j=js:je	
                    tmpres=abs(-1d0*T(i,j)+(fpc(i,j,1)*T(i+1,j)+fpc(i,j,2)*T(i,j+1)+...
                                fpc(i,j,4)*T(i-1,j)+fpc(i,j,5)*T(i,j-1)+...
                                fpc(i,j,6)));
                    if(res<tmpres)
                        res=tmpres;
                    end
				end; end			
				if(res<MaxError)it;break;end
				if (res>1e10) %stop '***** solution has diverged *****'
			      error(['Diverged after ',num2str(it),' iterations.-Pressure-LinearSolver called by Poisson equation']);
                end				
			
        end	
    end    
    
=========================================================================
       
end    