module fonctions
  
  ! module principal contenant les sous-routines de ce tp  
  implicit none
  
  
contains
  

  ! Initialisation u
  subroutine init(u,x,nx)
    implicit none
   
    real*8, intent(inout), dimension (:) :: u,x
    integer , intent(in) :: nx
    integer  :: i
    
    
    do i=1, nx
       u(i) = x(i)**2
    enddo
    
    
  end subroutine  Init
  

  ! Euler explicite
  subroutine Euler_ex(u, u_next,dt,dx,nx)
    implicit none
    real*8, intent(in), dimension (:) :: u
    real*8, intent(inout), dimension (:) :: u_next
    real*8 , intent(in) :: dt,dx
    integer , intent(in) :: nx
    integer  :: i
     real*8 :: a, b

     a = 0.
     b = 1.
   
    do i=2, nx-1
       u_next(i) = u(i) + dt*(u(i+1)-2.*u(i)+u(i-1))/dx**2
    enddo
    u_next(1) = u(1) + dt*(u(2)-2.*u(1)+a)/dx**2
    u_next(nx) = u(nx) + dt*(b-2.*u(nx)+u(nx-1))/dx**2

    
  end subroutine  Euler_ex
  
  
  
end module fonctions




!  Programme principal

program Chaleur_DF
  
  use fonctions
  
  implicit none
 
  real*8,ALLOCATABLE:: u(:), u_next(:),x(:)
  real*8 :: dt, tmax, dx, xmax, xmin
  integer :: nb_iter,i, nfreq,k, nx,nbre
  character(len=50) :: mystr
  
  nx = 10

  write(*,*) 'Entrez le temps final'
  read(*,*) tmax
  write(*,*) 'Entrez dt'
  read(*,*) dt
  write(*,*) 'Entrez nx'
  read(*,*) nx
  write(*,*) 'Entrez nfreq'
  read(*,*) nfreq
  
  xmin = 0.
  xmax = 1.
!!$
  dx = (xmax-xmin)/(nx+1)
  nb_iter = ceiling(tmax/dt)
  
 
  ! Initialisation
   allocate(u(1:nx))
   allocate(u_next(1:nx))
   allocate(x(1:nx))

   do i=1,nx
      x(i) = i*dx
   enddo

   call init(u,x,nx)

 
  ! boucle temporelle principale
  do k = 1, nb_iter
     
     ! appel de la routine d'integration
     call Euler_ex(u, u_next,dt,dx,nx)
     u = u_next
     
     ! ecriture du resultat toutes les nfreq iterations
     
     if (mod(k,nfreq).eq.0) then
        
        nbre = k/nfreq
        write(mystr,'(i4.4)')nbre 
        open(222,file='u'//trim(mystr),position='append')
        
        !Ecriture dans le fichier 
        do i=1,nx
           write(222,*) x(i), u(i)
        enddo
        close(222)  

     endif
     
  end do
 
  deallocate(u,u_next,x)
  
end program

