wronskian.f90 Source File


Source Code

!------------------------------------------------------------------------------------
!> Summary: Calculation of the Wronskian of the wavefunctions for numerical tests
!> Author: David Bauer
!> Calculation of the Wronskian of the wavefunctions for numerical tests in the 
!> calculation of the t-matrix. The wronskian is calculated for both regular and
!> irregular solutions.
!------------------------------------------------------------------------------------
module mod_wronskian

contains
  !-------------------------------------------------------------------------------
  !> Summary: Calculation of the Wronskian of the wavefunctions for numerical tests
  !> Author: David Bauer
  !> Category: numerical-tools, sanity-check, KKRimp
  !> Deprecated: False
  !> Calculation of the Wronskian of the wavefunctions for numerical tests in the 
  !> calculation of the t-matrix. The wronskian is calculated for both regular and
  !> irregular solutions and saved in the files `test_wronskian` and `test_wronskian2`
  !> The Wronskian relations are defined in 4.37 and 4.45 of the PhD thesis by 
  !> David Bauer (pp. 48).
  !-------------------------------------------------------------------------------
  subroutine calcwronskian(rll, sll, leftrll, leftsll, ncheb, npan_tot, ipan_intervall, rpan_intervall)
    
    use mod_datatypes, only: dp
    use mod_mathtools, only: matmat1T, matmatT1, matvec_dzdz
    use mod_cheb, only: getCLambdaCinv
    implicit none
    ! interface
    complex (kind=dp), intent(in) :: rll(:,:,:) !! regular right wavefunction
    complex (kind=dp), intent(in) :: sll(:,:,:) !! irregular right wavefunction
    complex (kind=dp), intent(in) :: leftrll(:,:,:) !! regular left wavefunction
    complex (kind=dp), intent(in) :: leftsll(:,:,:) !! irregular left wavefunction
    integer, intent(in) :: ncheb    !! number of Chebychev polynomials
    integer, intent(in) :: npan_tot !! number of panels
    integer, intent(in) :: ipan_intervall(0:npan_tot) !! index array for potential and shapefunction boundaries for each panel
    real (kind=dp), intent(in) :: rpan_intervall(0:npan_tot) !! radial values of panel boundaries 
    ! local arrays
    complex (kind=dp), allocatable :: drlldr(:,:,:)     !! derivative of rll
    complex (kind=dp), allocatable :: dslldr(:,:,:)     !! derivative of sll
    complex (kind=dp), allocatable :: dleftrlldr(:,:,:) !! derivative of leftrll
    complex (kind=dp), allocatable :: dleftslldr(:,:,:) !! derivative of leftsll
    complex (kind=dp), allocatable :: fn(:),dfndr(:)    !! working arrays for radial derivatives
    complex (kind=dp), allocatable :: fn2(:),dfn2dr(:)  !! working arrays for radial derivatives
    complex (kind=dp), allocatable :: fn3(:),dfn3dr(:)  !! working arrays for radial derivatives
    complex (kind=dp), allocatable :: fn4(:),dfn4dr(:)  !! working arrays for radial derivatives
    complex (kind=dp), allocatable :: wronskian(:,:,:)  !! wronskian of the first kind (eq. 4.44, PhD Bauer)
    complex (kind=dp), allocatable :: wronskian2(:,:,:) !! wronskian of the second kind (eq. 4.37, PhD Bauer)
    complex (kind=dp) :: CLambdaCinv(0:ncheb,0:ncheb) !! complex version of integration matrix in Chebychev mesh (imaginary part is zero)
    real (kind=dp) :: CLambdaCinv_temp(0:ncheb,0:ncheb) !! integration matrix in Chebychev mesh
    real (kind=dp) :: widthfac !! width of panel = 1/2*(r(m)-r(m-1))
    ! working indices and matrix sizes
    integer :: ilm1,ilm2,ir,ipan,irstart,irstop
    integer :: lmsize,lmsize2,nrmax
  
    lmsize  = ubound(rll,2)
    lmsize2 = ubound(rll,1)
    nrmax   = ubound(rll,3)
  
    write(*,*) 'in calcwronskian:', lmsize, lmsize2, nrmax
    allocate( drlldr(lmsize2,lmsize,nrmax), dslldr(lmsize2,lmsize,nrmax) )
    allocate( dleftrlldr(lmsize2,lmsize,nrmax), dleftslldr(lmsize2,lmsize,nrmax) )
    allocate( wronskian(lmsize,lmsize,nrmax) )
    allocate( wronskian2(lmsize2,lmsize2,nrmax) )
    allocate( fn(nrmax), fn2(nrmax), dfndr(nrmax), dfn2dr(nrmax) )
    allocate( fn3(nrmax), fn4(nrmax), dfn3dr(nrmax), dfn4dr(nrmax) )
  
    ! ############################################################
    ! Differentiate the wave functions
    ! ############################################################

    ! construct Chebychev integration matrix
    call getCLambdaCinv(Ncheb, CLambdaCinv_temp(0:ncheb,0:ncheb))
    ! convert to complex numbers
    CLambdaCinv(0:ncheb,0:ncheb) = cmplx(CLambdaCinv_temp(0:ncheb,0:ncheb), 0.0_dp)
  
    ! perform radial derivative of rll, rllleft, sll and sllleft
    do ilm1=1,lmsize2
      do ilm2=1,lmsize
        fn =rll(ilm1,ilm2,:)
        fn2=sll(ilm1,ilm2,:)
        fn3=leftrll(ilm1,ilm2,:)
        fn4=leftsll(ilm1,ilm2,:)
        
        do ipan=1,npan_tot
          irstart=ipan_intervall(ipan-1)+1
          irstop = ipan_intervall(ipan)
          widthfac = 2.0_dp/(rpan_intervall(ipan)-rpan_intervall(ipan-1))
  
          dfndr(irstart:irstop) = matvec_dzdz(CLambdaCinv,fn(irstart:irstop))
          dfndr(irstart:irstop) = dfndr(irstart:irstop)*widthfac
          dfn2dr(irstart:irstop) = matvec_dzdz(CLambdaCinv,fn2(irstart:irstop))
          dfn2dr(irstart:irstop) = dfn2dr(irstart:irstop)*widthfac
          dfn3dr(irstart:irstop) = matvec_dzdz(CLambdaCinv,fn3(irstart:irstop))
          dfn3dr(irstart:irstop) = dfn3dr(irstart:irstop)*widthfac
          dfn4dr(irstart:irstop) = matvec_dzdz(CLambdaCinv,fn4(irstart:irstop))
          dfn4dr(irstart:irstop) = dfn4dr(irstart:irstop)*widthfac
        end do

        drlldr(ilm1,ilm2,:)=dfndr
        dslldr(ilm1,ilm2,:)=dfn2dr
        dleftrlldr(ilm1,ilm2,:)=dfn3dr
        dleftslldr(ilm1,ilm2,:)=dfn4dr
      end do 
    end do
  
    ! ############################################################
    ! Construct Wronskian
    ! ############################################################
    do ir=1,nrmax
      wronskian(:,:,ir)= matmatT1( dleftslldr(:,:,ir),rll(:,:,ir)  )
      wronskian2(:,:,ir)= matmat1T( rll(:,:,ir),leftsll(:,:,ir)  )
      wronskian(:,:,ir)= wronskian(:,:,ir) - matmatT1(leftsll(:,:,ir),drlldr(:,:,ir))
      wronskian2(:,:,ir)= wronskian2(:,:,ir) - matmat1T(sll(:,:,ir),leftrll(:,:,ir))
    end do 
  
    ! open output file for wronskian relations and write files out
    ! the files contail the left-hand site of eq. 4.44 and 4.37
    open(unit=9246760,file='test_rpan_intervall')
    write(9246760,'(50000F35.16)') rpan_intervall(:)
    close(unit=9246760)

    open(unit=9246761,file='test_rllleft')
    open(unit=9246762,file='test_sllleft')
    open(unit=9246763,file='test_rll')
    open(unit=9246764,file='test_sll')

    open(unit=3246762,file='test_wronskian')
    open(unit=3246763,file='test_wronskian2')
    write(3246762,'(a)') '# lm1, lm2, wronskian(lm1, lm2, 1:ir_max) (first kind)'
    write(3246763,'(a)') '# lm1, lm2, wronskian2(lm1, lm2, 1:ir_max) (second kind)'
  
    do ilm1=1, lmsize
      do ilm2=1, lmsize
        write(3246762,'(2i5,50000F35.16)') ilm2, ilm1, wronskian(ilm2,ilm1,:)
        write(9246761,'(2i5,50000F35.16)') ilm2, ilm1, leftrll(ilm2,ilm1,:)
        write(9246762,'(2i5,50000F35.16)') ilm2, ilm1, leftsll(ilm2,ilm1,:)
        write(9246763,'(2i5,50000F35.16)') ilm2, ilm1, rll(ilm2,ilm1,:)
        write(9246764,'(2i5,50000F35.16)') ilm2, ilm1, sll(ilm2,ilm1,:)
      end do
    end do
  
    do ilm1=1, lmsize2
      do ilm2=1, lmsize2
        write(3246763,'(2i5,50000F35.16)') ilm2, ilm1, wronskian2(ilm2,ilm1,:)
      end do
    end do
  
    close(3246762)
    close(3246763)

    close(9246761)
    close(9246762)
    close(9246763)
    close(9246764)
  
  end subroutine calcwronskian

end module mod_wronskian