PDEparabolic.f90 Source File


This file depends on

sourcefile~~pdeparabolic.f90~~EfferentGraph sourcefile~pdeparabolic.f90 PDEparabolic.f90 sourcefile~gbsv.f90 gbsv.f90 sourcefile~pdeparabolic.f90->sourcefile~gbsv.f90 sourcefile~phys_consts.f90 phys_consts.F90 sourcefile~pdeparabolic.f90->sourcefile~phys_consts.f90

Files dependent on this one

sourcefile~~pdeparabolic.f90~~AfferentGraph sourcefile~pdeparabolic.f90 PDEparabolic.f90 sourcefile~test_diffusion1d.f90 test_diffusion1D.f90 sourcefile~test_diffusion1d.f90->sourcefile~pdeparabolic.f90 sourcefile~diffusion.f90 diffusion.f90 sourcefile~diffusion.f90->sourcefile~pdeparabolic.f90 sourcefile~multifluid.f90 multifluid.f90 sourcefile~multifluid.f90->sourcefile~diffusion.f90 sourcefile~gemini.f90 gemini.f90 sourcefile~gemini.f90->sourcefile~multifluid.f90

Contents

Source Code


Source Code

module PDEparabolic

!! a module for use for solving parabolic partial differential equations


!> banded and tridiagonal solvers, for now we just take everything to be banded...
use phys_consts, only: wp
use vendor_lapack95, only: gbsv!,gtsv

implicit none

private
public :: TRBDF21D, backEuler1D


contains


function TRBDF21D(Ts,A,B,C,D,E,Tsminx1,Tsmaxx1,dt,dx1,dx1i)

!! SOLVE A 1D DIFFUSION PROBLEM.  IT IS EXPECTED THAT
!! GHOST CELLS WILL HAVE BEEN TRIMMED FROM ARRAYS BEFORE
!! THEY ARE PASSED INTO THIS ROUTINE.
!!
!! FORM OF EQUATION SOLVED IS:
!!  dT/dt + A T + B dT/dx + C d/dx(D dT/dx) = E
!!
!!  NOTE: UPON FURTHER REVIEW I THINK THE FORM SOLVED IS ACTUALLY:
!!  dT/dt = A T + B dT/dx + C d/dx(D dT/dx) + E

real(wp), dimension(:), intent(in) :: A,B,C,D,E
real(wp), dimension(:), intent(in) :: Ts
real(wp), intent(in) :: Tsminx1, Tsmaxx1, dt
real(wp), dimension(0:), intent(in) :: dx1   !ith backward difference
real(wp), dimension(:), intent(in) :: dx1i   !ith centered difference
integer, parameter :: ll=2                   !number of lower diagonals

real(wp), dimension(3*ll+1,size(Ts)) :: M    !note extra rows for lapack workspace
real(wp), dimension(size(Ts)) :: Dh
integer :: ix1,lx1

real(wp), dimension(size(Ts)) :: TR

real(wp), dimension(size(Ts)) :: TRBDF21D

!> ORGANIZE SIZES AND THERMAL CONDUCTIVITY
lx1=size(Ts)
Dh(1)=0.0
Dh(2:lx1)=0.5*(D(1:lx1-1)+D(2:lx1))         !ith left cell wall thermal conductivity
!    TR(:)=Ts(:)/dt+E(:)
!! boundaries to be overwritten later...  This is now done for each grid point in a separate statement


!! ## TR HALF STEP:  DEFINE A MATRIX USING BANDED STORAGE

!> MINX1 BOUNDARY (DIRICHLET)
ix1=1
M(ll+3,ix1)=1.0
M(ll+2,ix1+1)=0.0
M(ll+1,ix1+2)=0.0
TR(ix1)=Tsminx1


!> FIRST INTERIOR GRID POINT
ix1=2

!> ix1-1
M(ll+4,ix1-1)=-1*C(ix1)*Dh(ix1)/dx1i(ix1)/dx1(ix1)/2d0 &
           +B(ix1)/(dx1(ix1+1)+dx1(ix1))/2d0

!> ix1
M(ll+3,ix1)=1.0/(dt/2d0)-A(ix1)/2d0 &
         +C(ix1)*Dh(ix1+1)/dx1i(ix1)/dx1(ix1+1)/2d0 &
         +C(ix1)*Dh(ix1)/dx1i(ix1)/dx1(ix1)/2d0

!> ix1+1, super-diag.
M(ll+2,ix1+1)=-1*C(ix1)*Dh(ix1+1)/dx1i(ix1)/dx1(ix1+1)/2d0 &
         -1*B(ix1)/(dx1(ix1+1)+dx1(ix1))/2d0
M(ll+1,ix1+2)=0.0
TR(ix1)=Ts(ix1)/(dt/2d0)+E(ix1) &
  -M(ll+4,ix1-1)*Ts(ix1-1) &
  -(-A(ix1)/2d0+C(ix1)*Dh(ix1+1)/dx1i(ix1)/dx1(ix1+1)/2d0+C(ix1)*Dh(ix1)/dx1i(ix1)/dx1(ix1)/2d0)*Ts(ix1) &
  -M(ll+2,ix1+1)*Ts(ix1+1) &
  -M(ll+1,ix1+2)*Ts(ix1+2)


!> INTERIOR GRID POINTS
do concurrent (ix1=3:lx1-2)
  !! do concurrent OK because only indexing already defined things
  M(ll+5,ix1-2) = 0
  !! ix1-2 grid point, sub-diag.
  M(ll+4,ix1-1)=-1*C(ix1)*Dh(ix1)/dx1i(ix1)/dx1(ix1)/2d0 &        !ix1-1
             +B(ix1)/(dx1(ix1+1)+dx1(ix1))/2d0
  M(ll+3,ix1)=1.0/(dt/2d0)-A(ix1)/2d0 &                           !ix1
           +C(ix1)*Dh(ix1+1)/dx1i(ix1)/dx1(ix1+1)/2d0 &
           +C(ix1)*Dh(ix1)/dx1i(ix1)/dx1(ix1)/2d0
  M(ll+2,ix1+1)=-1*C(ix1)*Dh(ix1+1)/dx1i(ix1)/dx1(ix1+1)/2d0 &    !ix1+1, super-diag.
           -1*B(ix1)/(dx1(ix1+1)+dx1(ix1))/2d0
  M(ll+1,ix1+2) = 0
  !! ix1+2 grid point
  TR(ix1)=Ts(ix1)/(dt/2d0)+E(ix1) &
    -M(ll+5,ix1-2)*Ts(ix1-2) &
    -M(ll+4,ix1-1)*Ts(ix1-1) &
    -(-A(ix1)/2d0+C(ix1)*Dh(ix1+1)/dx1i(ix1)/dx1(ix1+1)/2d0+C(ix1)*Dh(ix1)/dx1i(ix1)/dx1(ix1)/2d0)*Ts(ix1) &
    -M(ll+2,ix1+1)*Ts(ix1+1) &
    -M(ll+1,ix1+2)*Ts(ix1+2)
end do


!> LAST INTERIOR GRID POINT
ix1=lx1-1
M(ll+5,ix1-2)=0.0
M(ll+4,ix1-1)=-1*C(ix1)*Dh(ix1)/dx1i(ix1)/dx1(ix1)/2d0 &            !ix1-1
           +B(ix1)/(dx1(ix1+1)+dx1(ix1))/2d0
M(ll+3,ix1)=1.0/(dt/2d0)-A(ix1)/2d0 &                               !ix1
         +C(ix1)*Dh(ix1+1)/dx1i(ix1)/dx1(ix1+1)/2d0 &
         +C(ix1)*Dh(ix1)/dx1i(ix1)/dx1(ix1)/2d0
M(ll+2,ix1+1)=-1*C(ix1)*Dh(ix1+1)/dx1i(ix1)/dx1(ix1+1)/2d0 &        !ix1+1, super-diag.
         -1*B(ix1)/(dx1(ix1+1)+dx1(ix1))/2d0
TR(ix1)=Ts(ix1)/(dt/2d0)+E(ix1) &
  -M(ll+5,ix1-2)*Ts(ix1-2) &
  -M(ll+4,ix1-1)*Ts(ix1-1) &
  -(-A(ix1)/2d0+C(ix1)*Dh(ix1+1)/dx1i(ix1)/dx1(ix1+1)/2d0+C(ix1)*Dh(ix1)/dx1i(ix1)/dx1(ix1)/2d0)*Ts(ix1) &
  -M(ll+2,ix1+1)*Ts(ix1+1)


!> MAXX1 BOUNDARY
ix1=lx1
M(ll+5,ix1-2)=0.0
M(ll+4,ix1-1)=0.0
M(ll+3,ix1)=1.0
TR(ix1)=Tsmaxx1


!! ### TR HALF STEP MATRIX SOLUTION:  CALL LAPACK'S BANDED SOLVER

!> BANDED SOLVER (INPUT MATRIX MUST BE SHIFTED 'DOWN' BY KL ROWS)
call gbsv(M,TR,kl=2)



!! ## BDF2 STEP:  DEFINE A MATRIX USING BANDED STORAGE

!> MINX1 BOUNDARY (DIRICHLET)
ix1=1
M(ll+3,ix1)=1.0
M(ll+2,ix1+1)=0.0
M(ll+1,ix1+2)=0.0
TRBDF21D(ix1)=Tsminx1


!> FIRST INTERIOR GRID POINT
ix1=2
M(ll+4,ix1-1)=-1*C(ix1)*Dh(ix1)/dx1i(ix1)/dx1(ix1) &            !ix1-1
           +B(ix1)/(dx1(ix1+1)+dx1(ix1))
M(ll+3,ix1)=1.0/(dt/3._wp)-A(ix1) &                               !ix1
         +C(ix1)*Dh(ix1+1)/dx1i(ix1)/dx1(ix1+1) &
         +C(ix1)*Dh(ix1)/dx1i(ix1)/dx1(ix1)
M(ll+2,ix1+1)=-1*C(ix1)*Dh(ix1+1)/dx1i(ix1)/dx1(ix1+1) &        !ix1+1, super-diag.
         -1*B(ix1)/(dx1(ix1+1)+dx1(ix1))
M(ll+1,ix1+2)=0.0
TRBDF21D(ix1)=E(ix1) &
  -1._wp/3._wp*Ts(ix1)/(dt/3._wp) &
  +4._wp/3._wp*TR(ix1)/(dt/3._wp)


!> INTERIOR GRID POINTS
do concurrent (ix1=3:lx1-2)
  M(ll+5,ix1-2)=0.0                                               !ix1-2 grid point, sub-diag.
  M(ll+4,ix1-1)=-1*C(ix1)*Dh(ix1)/dx1i(ix1)/dx1(ix1) &        !ix1-1
             +B(ix1)/(dx1(ix1+1)+dx1(ix1))
  M(ll+3,ix1)=1.0/(dt/3._wp)-A(ix1) &                           !ix1
           +C(ix1)*Dh(ix1+1)/dx1i(ix1)/dx1(ix1+1) &
           +C(ix1)*Dh(ix1)/dx1i(ix1)/dx1(ix1)
  M(ll+2,ix1+1)=-1*C(ix1)*Dh(ix1+1)/dx1i(ix1)/dx1(ix1+1) &    !ix1+1, super-diag.
           -1*B(ix1)/(dx1(ix1+1)+dx1(ix1))
  M(ll+1,ix1+2)=0.0                                               !ix1+2 grid point
  TRBDF21D(ix1)=E(ix1) &
    -1._wp/3._wp*Ts(ix1)/(dt/3._wp) &
    +4._wp/3._wp*TR(ix1)/(dt/3._wp)
end do


!LAST INTERIOR GRID POINT
ix1=lx1-1
M(ll+5,ix1-2)=0.0
M(ll+4,ix1-1)=-1*C(ix1)*Dh(ix1)/dx1i(ix1)/dx1(ix1) &            !ix1-1
           +B(ix1)/(dx1(ix1+1)+dx1(ix1))
M(ll+3,ix1)=1.0/(dt/3._wp)-A(ix1) &                               !ix1
         +C(ix1)*Dh(ix1+1)/dx1i(ix1)/dx1(ix1+1) &
         +C(ix1)*Dh(ix1)/dx1i(ix1)/dx1(ix1)
M(ll+2,ix1+1)=-1*C(ix1)*Dh(ix1+1)/dx1i(ix1)/dx1(ix1+1) &        !ix1+1, super-diag.
         -1*B(ix1)/(dx1(ix1+1)+dx1(ix1))
TRBDF21D(ix1)=E(ix1) &
  -1._wp/3._wp*Ts(ix1)/(dt/3._wp) &
  +4._wp/3._wp*TR(ix1)/(dt/3._wp)

!> MAXX1 BOUNDARY
ix1=lx1
M(ll+5,ix1-2)=0.0
M(ll+4,ix1-1)=0.0
M(ll+3,ix1)=1.0
TRBDF21D(ix1)=Tsmaxx1


!! ## BDF2 STEP MATRIX SOLUTION:  CALL LAPACK'S BANDED SOLVER

!> BANDED SOLVER (INPUT MATRIX MUST BE SHIFTED 'DOWN' BY KL ROWS)
call gbsv(M,TRBDF21D,kl=2)

end function TRBDF21D


function backEuler1D(Ts,A,B,C,D,E,Tsminx1,Tsmaxx1,dt,dx1,dx1i)

!------------------------------------------------------------
!-------SOLVE A 1D DIFFUSION PROBLEM.  IT IS EXPECTED THAT
!-------GHOST CELLS WILL HAVE BEEN TRIMMED FROM ARRAYS BEFORE
!-------THEY ARE PASSED INTO THIS ROUTINE.  FORM OF EQUATION
!-------SOLVED IS:
!------- dT/dt + A T + B dT/dx + C d/dx(D dT/dx) = E
!------------------------------------------------------------

real(wp), dimension(:), intent(in) :: A,B,C,D,E
real(wp), dimension(:), intent(in) :: Ts
real(wp), intent(in) :: Tsminx1, Tsmaxx1, dt
real(wp), dimension(0:), intent(in) :: dx1   !ith backward difference
real(wp), dimension(:), intent(in) :: dx1i   !ith centered difference
integer, parameter :: ll=2                   !number of lower diagonals

real(wp), dimension(3*ll+1,size(Ts)) :: M    !note extra rows for lapack workspace
real(wp), dimension(size(Ts)) :: Dh

real(wp), dimension(size(Ts)) :: backEuler1D

integer :: ix1,lx1

!------------------------------------------------------------
!-------DEFINE A MATRIX USING BANDED STORAGE
!------------------------------------------------------------
lx1=size(Ts)
Dh(1)=0.0
Dh(2:lx1)=0.5*(D(1:lx1-1)+D(2:lx1))         !ith left cell wall thermal conductivity
backEuler1D(:)=Ts(:)/dt+E(:)                !boundaries to be overwritten later...


!> MINX1 BOUNDARY
ix1=1
M(ll+3,ix1)=1.0
M(ll+2,ix1+1)=0.0
M(ll+1,ix1+2)=0.0
backEuler1D(ix1)=Tsminx1


!> FIRST INTERIOR GRID POINT
ix1=2
M(ll+4,ix1-1)=-1*C(ix1)*Dh(ix1)/dx1i(ix1)/dx1(ix1) &            !ix1-1
           +B(ix1)/(dx1(ix1+1)+dx1(ix1))
M(ll+3,ix1)=1.0/dt-A(ix1) &                                     !ix1
         +C(ix1)*Dh(ix1+1)/dx1i(ix1)/dx1(ix1+1) &
         +C(ix1)*Dh(ix1)/dx1i(ix1)/dx1(ix1)
M(ll+2,ix1+1)=-1*C(ix1)*Dh(ix1+1)/dx1i(ix1)/dx1(ix1+1) &        !ix1+1, super-diag.
         -1*B(ix1)/(dx1(ix1+1)+dx1(ix1))
M(ll+1,ix1+2)=0.0


!> INTERIOR GRID POINTS
do concurrent (ix1=3:lx1-2)
  M(ll+5,ix1-2) = 0
  !! ix1-2 grid point, sub-diag.
  M(ll+4,ix1-1)=-1*C(ix1)*Dh(ix1)/dx1i(ix1)/dx1(ix1) &            !ix1-1
             +B(ix1)/(dx1(ix1+1)+dx1(ix1))
  M(ll+3,ix1)=1.0/dt-A(ix1) &                                     !ix1
           +C(ix1)*Dh(ix1+1)/dx1i(ix1)/dx1(ix1+1) &
           +C(ix1)*Dh(ix1)/dx1i(ix1)/dx1(ix1)
  M(ll+2,ix1+1)=-1*C(ix1)*Dh(ix1+1)/dx1i(ix1)/dx1(ix1+1) &        !ix1+1, super-diag.
           -1*B(ix1)/(dx1(ix1+1)+dx1(ix1))
  M(ll+1,ix1+2) = 0
  !! ix1+2 grid point
end do


!> LAST INTERIOR GRID POINT
ix1=lx1-1
M(ll+5,ix1-2)=0.0
M(ll+4,ix1-1)=-1*C(ix1)*Dh(ix1)/dx1i(ix1)/dx1(ix1) &            !ix1-1
           +B(ix1)/(dx1(ix1+1)+dx1(ix1))
M(ll+3,ix1)=1.0/dt-A(ix1) &                                     !ix1
         +C(ix1)*Dh(ix1+1)/dx1i(ix1)/dx1(ix1+1) &
         +C(ix1)*Dh(ix1)/dx1i(ix1)/dx1(ix1)
M(ll+2,ix1+1)=-1*C(ix1)*Dh(ix1+1)/dx1i(ix1)/dx1(ix1+1) &        !ix1+1, super-diag.
         -1*B(ix1)/(dx1(ix1+1)+dx1(ix1))


!> MAXX1 BOUNDARY
ix1=lx1
M(ll+5,ix1-2)=0.0
M(ll+4,ix1-1)=0.0
M(ll+3,ix1)=1.0
backEuler1D(ix1)=Tsmaxx1


!! ## DO SOME STUFF TO CALL LAPACK'S BANDED SOLVER

!> BANDED SOLVER (INPUT MATRIX MUST BE SHIFTED 'DOWN' BY KL ROWS)
call gbsv(M,backEuler1D,kl=2)

end function backEuler1D


end module PDEparabolic