! ! MIXLBM.f90 ! ! FUNCTIONS: ! MIXLBM - Main ! UpdateLatticeData - Update local distribution function f in P(i,j) ! HydrodynamicMoments - Compute hydrodynamic moments of f ! EquilibriumDistribution - Compute the equilibrium distribution function feq ! D(M) - Fick diffusivity ! B(M1,M2) - Stefan-Maxwell resistivity ! writeDAT - write results to files ! !**************************************************************************** ! ! PROGRAM: MIXLBM ! ! PURPOSE: To compare different implementations of species coupling ! (Fick model, Maxwell-Stefan) in LBM framework ! !**************************************************************************** program MIXLBM implicit none ! Local variables: vectors real(8),dimension(:,:,:,:),allocatable :: fd,fd_new real(8),dimension(:,:),allocatable :: f real(8),dimension(:,:,:,:),allocatable :: rsigma,psigma,uxsigma,uysigma real(8),dimension(:,:),allocatable :: r,p,ux,uy real(8),dimension(:),allocatable :: phi real(8),dimension(:,:),allocatable :: BCsigma real(8),dimension(:,:),allocatable :: Output real(8),dimension(:),allocatable :: MM real(8),dimension(0:8) :: feq ! Local variables: scalars real(8) :: rho_new,ux_new,uy_new integer :: nx,ny,nt integer :: species,md integer :: i,j,k,s,t ! Values species = 3; nx = 100; ny = 10; nt = 30; ! Physical model ! 0- Ideal Fick model ! 1- Fick model ! 2- Maxwell-Stefan model md = 2; ! Allocate memory allocate( fd(1:nx,1:ny,0:8,1:species) ) allocate( fd_new(1:nx,1:ny,0:8,1:species) ) allocate( f(0:8,1:species) ) allocate( rsigma(1:nx,1:ny,1:species,0:nt) ) allocate( psigma(1:nx,1:ny,1:species,0:nt) ) allocate( uxsigma(1:nx,1:ny,1:species,0:nt) ) allocate( uysigma(1:nx,1:ny,1:species,0:nt) ) allocate( r(1:nx,1:ny) ) allocate( p(1:nx,1:ny) ) allocate( ux(1:nx,1:ny) ) allocate( uy(1:nx,1:ny) ) allocate( phi(1:species) ) allocate( BCsigma(1:4,1:species) ) allocate( MM(1:species) ) allocate( Output(1:nx,1:ny) ) ! Molecular weight MM(1) = 1.0d0; MM(2) = 2.0d0; MM(3) = 3.0d0; ! R0*T = 2.0 in lattice units, where R0 universal gas constant phi(1) = 1.0d0/MM(1); phi(2) = 1.0d0/MM(2); phi(3) = 1.0d0/MM(3); ! Boundary conditions BCsigma(:,1) = (/0.45d0, -1.0d0, 0.55d0, -1.0d0/); BCsigma(:,2) = (/0.50d0, -1.0d0, 0.50d0, -1.0d0/); BCsigma(:,3) = (/0.55d0, -1.0d0, 0.45d0, -1.0d0/); !============================================================================ ! Initialization !============================================================================ do i = 1,nx,1 do j = 1,ny,1 ! Species 1 if (i0 Dirichlet, rho = BC(i) ! 1, 0, -1, 0 ! 0, 1, 0, -1 real(8),dimension(1:4,1:species),intent(in) :: BCs ! new distribution function in P(i,j) real(8),dimension(0:8,1:species),intent(out) :: newfdPs ! Local variables real(8),dimension(:),allocatable :: rsigma,psigma,uxsigma,uysigma real(8),dimension(:),allocatable :: uxstar,uystar real(8),dimension(:,:),allocatable :: f real(8),dimension(:),allocatable :: lambda real(8),dimension(0:8) :: feq,fcoll integer,dimension(0:8,1:2) :: Incr integer,dimension(0:8) :: BB real(8) :: r,p,ux,uy real(8) :: vx,vy real(8) :: temp,temp1,temp2 real(8) :: MM integer :: k,s,vs,ik,iik,iI,jI integer :: BCdirection ! Allocate memory allocate( f(0:8,1:species) ) allocate( rsigma(1:species) ) allocate( psigma(1:species) ) allocate( uxsigma(1:species) ) allocate( uysigma(1:species) ) allocate( lambda(1:species) ) allocate( uxstar(1:species) ) allocate( uystar(1:species) ) Incr(:,1) = (/0, 1, 0, -1, 0, 1, -1, -1, 1/) ! x-axis Incr(:,2) = (/0, 0, 1, 0, -1, 1, 1, -1, -1/) ! y-axis BB(:) = (/0,3,4,1,2,7,8,5,6/) ! bounce-back do k=0,8,1 iI = i + Incr(k,1); jI = j + Incr(k,2); do s=1,species,1 rsigma(s) = 0.0d0; psigma(s) = 0.0d0; uxsigma(s) = 0.0d0; uysigma(s) = 0.0d0; ! Boundary Conditions BCdirection = 0; if (iI>nx) then ! BC-1 BCdirection = 1; elseif (jI>ny) then ! BC-2 BCdirection = 2; elseif (iI<1) then ! BC-3 BCdirection = 3; elseif (jI<1) then ! BC-4 BCdirection = 4; endif if (BCdirection == 0) then ! bulk domain do ik=0,8,1 f(ik,s) = fd(iI,jI,ik,s); enddo call HydrodynamicMoments(f(:,s),rsigma(s),uxsigma(s),uysigma(s)) psigma(s) = rsigma(s)*phi(s)/3.0d0; else ! boundary layer if (BCs(BCdirection,s)<0) then ! wall: specify ux, uy do ik=0,8,1 f(ik,s) = fd(i,j,ik,s); enddo call HydrodynamicMoments(f(:,s),rsigma(s),uxsigma(s),uysigma(s)) uxsigma(s) = 0.0d0; uysigma(s) = 0.0d0; psigma(s) = rsigma(s)*phi(s)/3.0d0; call EquilibriumDistribution(rsigma(s),phi(s),uxsigma(s),uysigma(s),f(:,s)) else ! source: specify rho do ik=0,8,1 f(ik,s) = fd(i,j,ik,s); enddo call HydrodynamicMoments(f(:,s),rsigma(s),uxsigma(s),uysigma(s)) psigma(s) = BCs(BCdirection,s); rsigma(s) = 3.0d0*psigma(s)/phi(s); call EquilibriumDistribution(rsigma(s),phi(s),uxsigma(s),uysigma(s),f(:,s)) endif endif enddo r = 0.0d0; p = 0.0d0; do s=1,species,1 r = r + rsigma(s); p = p + psigma(s); enddo ! Barycentric quantities ux = 0.0d0; uy = 0.0d0; do s=1,species,1 ux = ux + ( rsigma(s)/r )*uxsigma(s); uy = uy + ( rsigma(s)/r )*uysigma(s); enddo ! Molar quantities vx = 0.0d0; vy = 0.0d0; do s=1,species,1 vx = vx + ( psigma(s)/p )*uxsigma(s); vy = vy + ( psigma(s)/p )*uysigma(s); enddo ! Molecular weight for mixture temp = 0.0d0; do s=1,species,1 temp = temp + ( rsigma(s)/r )/MMs(s); enddo MM = 1/temp; ! Modified quantities (Maxwell-Stefan) do s=1,species,1 uxstar(s) = uxsigma(s); uystar(s) = uysigma(s); do vs=1,species,1 uxstar(s) = uxstar(s) + (MM**2)/(MMs(s)*MMs(vs))* & B(MMs(s),MMs(vs))/B(MMs(s),MMs(s))* & ( rsigma(vs)/r )*(uxsigma(vs)-uxsigma(s)); uystar(s) = uystar(s) + (MM**2)/(MMs(s)*MMs(vs))* & B(MMs(s),MMs(vs))/B(MMs(s),MMs(s))* & ( rsigma(vs)/r )*(uysigma(vs)-uysigma(s)); enddo enddo do s=1,species,1 ! Select your model if (model==0) then ! Ideal Fick model call EquilibriumDistribution(rsigma(s),phi(s),0.0d0,0.0d0,feq) lambda(s) = phi(s)/( 3.0d0*D(MMs(s)) ); elseif (model==1) then ! Fick model call EquilibriumDistribution(rsigma(s),phi(s),vx,vy,feq) lambda(s) = phi(s)/( 3.0d0*D(MMs(s)) ); elseif (model==2) then ! Maxwell-Stefan model call EquilibriumDistribution(rsigma(s),phi(s),uxstar(s),uystar(s),feq) lambda(s) = p*B(MMs(s),MMs(s))/r; endif ! Collision Step do ik=0,8,1 fcoll(ik) = f(ik,s)+lambda(s)*( feq(ik)-f(ik,s) ); enddo ! Streaming Step ! only one component in BB(k) direction is streamed ! BB(k) is an operator which produce the direction ! opposite to direction k newfdPs(BB(k),s) = fcoll(BB(k)); enddo enddo deallocate( f ) deallocate( rsigma ) deallocate( psigma ) deallocate( uxsigma ) deallocate( uysigma ) deallocate( lambda ) deallocate( uxstar ) deallocate( uystar ) end subroutine UpdateLatticeData !&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& real(8) function B(m1,m2) ! ! Binary resistivity of Maxwell-Stefan ! for couple (sigma , varsigma) species ! ** it depends on both species !! ** implicit none ! Inlet/Outlet real(8),intent(in) :: m1,m2 B = (1.0d0/m1+1.0d0/m2)**(-0.5d0); return end function B !&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& real(8) function D(m) ! ! Diffusivity of Fick ! for ( sigma ) species ! ** it depends on one species !! ** implicit none ! Inlet/Outlet real(8),intent(in) :: m D = 1.d0/m; return end function D !&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& subroutine writeDAT(nx,ny,M,name) implicit none ! Inlet integer,intent(in) :: nx,ny real(8),dimension(1:nx,1:ny),intent(in) :: M character(8),intent(in) :: name ! Local variables integer :: i,j integer :: IO_Stat_Number1=-1 open(UNIT=1,FILE=name,IOSTAT=IO_Stat_Number1) if (IO_Stat_Number1==0) then print *,'Saving ',name,' ...' do j=ny,1,-1 do i=1,nx,1 if (i