explicit.f90 Source File

Source Code

program explicit_diffusion
use input_output
use linear_algebra
use mesh
implicit none

real(8), allocatable, dimension(:)      ::      x_source, s_source
real(8), allocatable, dimension(:)      ::      x
real(8)                                 ::      Phi, D
real(8)                                 ::      x_total, delta_x, delta_x_min
integer(4)                              ::      n_x
real(8)                                 ::      t_final, delta_t, t
integer(4)                              ::      n_t
integer(4)                              ::      i, j, n
real(8), allocatable, dimension(:)      ::      Ckm1, S
real(8), allocatable, dimension(:)      ::      C
real(8)                                 ::      delta_xj, delta_xjm1, flux
real(8)                                 ::      k_r
logical                                 ::      debug=.FALSE.
real(8)                                 ::      t_save
real(8)                                 ::      t_step
integer(4)                              ::      n_file

! setting up the parameters
call init(Phi, t_final, t_save, t_step, D, k_r, x_total, delta_x, delta_x_min, n_x)

! Setting up the workspace
call workspace_setup()

!! Read in the inital distribution from a SRIM file
if (debug) write(*,*) "---- Reading the source input file..."
call read_srim("RANGE.txt", x_source, s_source)
!! convert the depth coordinates in x from angstroms to cm
x_source = x_source * 1.0d-8
!! convert the ion deposition source from atoms/cm^3 / atoms/cm^2 to just
!! atoms/cm^3 by multiplying by the fluence
s_source = s_source * Phi

!! Create a mesh
if (debug) write(*,*) "---- Creating a mesh..."
call uniformmesh(0.0d0, x_total, delta_x, n_x, x)
! now calculate our t step for stability
delta_t = delta_x**2.0d0 / (2.0d0 * D)
n_t = t_final / delta_t

if (debug) write(*,*) "---- Allocating matrices..."
allocate(C(n_x), Ckm1(n_x), S(n_x))
!! The source term never changes, so we can calculate this only once
if (debug) write(*,*) "---- Populating integral source vector..."
do j = 1, n_x
    S(j) = interp(x_source, s_source, x(j)) * delta_t
end do
Ckm1 = 0.0d0
do j=1, n_x
  C(j) = S(j)
end do
n_file = 0
call print_output(n_file, x, C, 0.0d0)
n_file = n_file + 1
!! now we can go through the time steps
if (debug) write(*,*) "---- Starting time analysis..."
t = 0.0d0
do i = 1, n_t
  ! iterate through the grid
  do j = 1, n_x
      delta_xj = ((x(j) - x(j - 1)) + &
		     (x(j + 1) - x(j)))/2.0d0
	    delta_xjm1 = (x(j) - x(j - 1))
      ! perform the predictor step (euler)
      if (j .eq. 1) then
          flux = - k_r * Ckm1(j)**2.0d0 / D + D * (Ckm1(j + 1) - 2.0d0 * &
            Ckm1(j) + Ckm1(j - 1)) / (delta_xj)/delta_xj
      else
          flux = D * (Ckm1(j + 1) - 2.0d0 * Ckm1(j) + Ckm1(j - 1)) / &
              (delta_xj)/delta_xj
      end if
	C(j) = Ckm1(j) + flux * delta_t + S(j)
  end do
  C(n_x) = 0.0d0
  ! save our updated array to the "last step" array and the ghost cells
  Ckm1 = C
  if (dabs(t - t_save) < 1.0d-15) then
      call print_output(n_file, x, C, t)
      n_file = n_file + 1
      t_save = t_save + t_step
  end if
  t = t + delta_t
  if (debug) write(*,*) "---- Next time step..."
end do

deallocate(C, Ckm1, S)
end program