Ce code permet de résoudre numériquement par différences finis l'équation de convection bidimensionnelle. Le code implémente un schéma décentré et facile à le convertir pour qu'il soit volume finis.
!-----------------------------------------------------------------------------! ! FD Method for solving convection equation in 2D ! du/dt = vx(du/dx )+ vy(du/dy) + q(x,y) ! Upwind scheme + 1D Euler ! Drichlet b.c. !-----------------------------------------------------------------------------! ! Written by Elmiloud Chaabelasri ! University Mohammed First ! Faculty of sciences, Oujda, Morocco ! chaabelasri@gmail.com ! ! Last updated: Jul. 06, 2019 !-----------------------------------------------------------------------------! program Conv2d implicit none integer::i,j,k,nx,ny,nt,ns,nf real*8 ::dx,dy,dt,x0,xL,y0,yL,t,Tmax,alpha real*8 ::vx,vy real*8,allocatable ::u(:,:),x(:),y(:),fluxx(:,:),fluxy(:,:) !Domain x0 =-1.0d0 !left xL = 1.0d0 !right y0 =-1.0d0 !bottom yL = 1.0d0 !up !number of points nx = 50 ny = 50 !Velocity fields vx=1.d0 vy=1.d0 !grid spacing (spatial) dx = (xL-x0)/dfloat(nx) dy = (yL-y0)/dfloat(ny) !spatial coordinates allocate(x(0:nx)) do i=0,nx x(i) = x0 + dfloat(i)*dx end do allocate(y(0:ny)) do j=0,ny y(j) = y0 + dfloat(j)*dy end do !maximum time desired Tmax = 1.d0 !diffusion constant: alpha = 1.0d0 !time step dt = 0.005d0 !number of points in time nt = nint(Tmax/dt) !number of snapshots to plot ns = nint(dfloat(nt)/10) !frequency for plotting nf = nint(dfloat(nt)/dfloat(ns)) !u: convected variable allocate(u(0:nx,0:ny)) allocate(fluxx(0:nx,0:ny)) allocate(fluxy(0:nx,0:ny)) !initial condition t = 0.0d0 do j=0,ny do i=0,nx u(i,j) = 0.0d0 if( x(i).gt.-0.9d0 .and. x(i).lt.-0.60 .and. & y(j).gt.-0.9d0 .and. y(j).lt.-0.6d0 )then u(i,j) = 1.d0 endif end do end do !Plot initial condition open(19,file='Initial.plt') write(19,*) 'variables ="x","y","u"' write(19,100)'zone f=point i=',nx+1,',j=',ny+1,',t="time',t,'"' do j=0,ny do i=0,nx write(19,*) x(i),y(j),u(i,j) end do end do close(19) ! open(18,file='EvolutionShow.plt') ! write(18,*) 'variables ="x","y","u"' ! write(18,100)'zone f=point i=',nx+1,',j=',ny+1,',t="time',t,'"' ! do j=0,ny ! do i=0,nx ! write(18,*) x(i),y(j),u(i,j) ! end do ! end do !time integration do k=1,nt ! Calcul flux at interfaces call CalculFlux(nx,ny,dx,dy,dt,t,alpha,x,y,u,fluxx,fluxy) !Time marching do j=1,ny-1 do i=1,nx-1 u(i,j) = u(i,j) - (vx*dt/dx)*(fluxx(i,j) - fluxx(i-1,j) ) & - (vy*dt/dy)*(fluxy(i,j) - fluxy(i,j-1) ) end do end do !Boundary conditions !Bottom and top do i=1,nx u(i,0) = u(i,1) u(i,ny) = u(i,nx-1) end do !right and left do j=1,ny u(0,j) = u(1,j) u(nx-1,j) = u(nx-1,j) end do !update t t = t+dt !plot field ! if (mod(k,nf).eq.0) then ! write(18,100)'zone f=point i=',nx+1,',j=',ny+1,',t="time',t,'"' ! do j=0,ny ! do i=0,nx ! write(18,*) x(i),y(j),u(i,j) ! end do ! end do ! end if print*,k,t,maxval(u) end do close(18) !Plot initial condition open(18,file='Finale.plt') write(18,*) 'variables ="x","y","u"' write(18,100)'zone f=point i=',nx+1,',j=',ny+1,',t="time',t,'"' do j=0,ny do i=0,nx write(18,*) x(i),y(j),u(i,j) end do end do 100 format(a16,i8,a4,i8,a10,f10.4,a3) end !-----------------------------------------------------------------------------! ! Calcul flux with DF !-----------------------------------------------------------------------------! subroutine CalculFlux(nx,ny,dx,dy,dt,t,alpha,x,y,u,fluxx,fluxy) implicit none integer::nx,ny,i,j real*8 ::dx,dy,dt,t,alpha real*8 ::u(0:nx,0:ny),x(0:nx),y(0:ny) real*8 ::fluxx(0:nx,0:ny),fluxy(0:nx,0:ny) do j=0,ny do i=0,nx fluxx(i,j) = u(i,j) fluxy(i,j) = u(i,j) end do end do end
0 Commentaires