!-----------------------------------------------------------------------------------------! ! Copyright (c) 2018 Peter Grünberg Institut, Forschungszentrum Jülich, Germany ! ! This file is part of Jülich KKR code and available as free software under the conditions! ! of the MIT license as expressed in the LICENSE.md file in more detail. ! !-----------------------------------------------------------------------------------------! !------------------------------------------------------------------------------------ !> Summary: Calculates the regular solution of the schroedinger equation or in semi relativistic approximation for a spherically averaged potential and given energy !> Author: B. Drittler !> Calculates the regular solution of the schroedinger equation or in semi relativistic !> approximation for a spherically averaged potential and given energy. !> To archieve greater presion the leading power \(r^s\) (in schroedinger case s = l, !> in case of sra \(s = \sqrt{ (l^2+l-1) - \frac{4z^2}{c^2} } )\) is analytically separated !> from the wavefunction. !> The t-matrix has to be determined at the mt radius in case of a mt calculation !> or at the ws radius in case of a ws calculation. Therefore the logarithmic !> derivative is calculated at that point (`=ircut(ipan)` ) !------------------------------------------------------------------------------------ !> @note Ph. Mavropoulos March 2003 - Dec 2004, Munich/Juelich: LDA+U included !> @endnote !------------------------------------------------------------------------------------ module mod_regsol use :: mod_datatypes, only: dp private :: dp contains !------------------------------------------------------------------------------- !> Summary: Calculates the regular solution of the schroedinger equation or in semi relativistic approximation for a spherically averaged potential and given energy !> Author: B. Drittler !> Category: lda+u, KKRhost !> Deprecated: False !> Calculates the regular solution of the schroedinger equation or in semi relativistic !> approximation for a spherically averaged potential and given energy. !> To archieve greater presion the leading power \(r^s\) (in schroedinger case s = l, !> in case of sra \(s = \sqrt{ (l^2+l-1) - \frac{4z^2}{c^2} } )\) is analytically separated !> from the wavefunction. !> The t-matrix has to be determined at the mt radius in case of a mt calculation !> or at the ws radius in case of a ws calculation. Therefore the logarithmic !> derivative is calculated at that point (`=ircut(ipan)` ) !------------------------------------------------------------------------------- !> @note Ph. Mavropoulos March 2003 - Dec 2004, Munich/Juelich: LDA+U included !> @endnote !------------------------------------------------------------------------------- subroutine regsol(cvlight,e,nsra,dlogdp,fz,hamf,mass,pz,dror,r,s,vm2z,z,ipan, & ircut,idoldau,lopt,wldauav,cutoff,irmd,ipand,lmaxd) use :: mod_datatypes implicit none ! .. Scalar Arguments .. complex (kind=dp) :: e real (kind=dp) :: cvlight, z, wldauav integer :: ipan, ipand, irmd, lmaxd, nsra, idoldau, lopt ! .. ! .. Array Arguments .. complex (kind=dp) :: dlogdp(0:lmaxd), fz(irmd, 0:lmaxd), hamf(irmd, 0:lmaxd) complex (kind=dp) :: mass(irmd), pz(irmd, 0:lmaxd) real (kind=dp) :: dror(irmd), r(irmd), s(0:lmaxd), vm2z(irmd) real (kind=dp) :: cutoff(irmd) integer :: ircut(0:ipand) ! .. ! .. Local Scalars .. complex (kind=dp) :: dfd0, dpd0, fip0, fip1, hamf1, k1f, k1p, k2f, k2p, k3f, k3p complex (kind=dp) :: k4f, k4p, mass1, pip0, pip1, vme, vmefac, vmetr1 real (kind=dp) :: dror1, drsm1, drsp1, s1, sm1, sp1, srafac integer :: ip, ir, irc, ire, irs, irsp1, j, k, l ! .. ! .. Local Arrays .. complex (kind=dp) :: a(-1:4), b(0:4), dfdi(-4:0), dpdi(-4:0) complex (kind=dp) :: hamfldau(irmd) ! .. ! .. Intrinsic Functions .. intrinsic :: cmplx, real ! .. if (nsra==2) then ! ---> in case of sra srafac = 1/c - otherwise srafac = 0 srafac = 1.0e0_dp/cvlight else srafac = 0.0e0_dp end if irc = ircut(ipan) do ir = 2, irc vmetr1 = (vm2z(ir)-e)*r(ir) - 2.0e0_dp*z hamf(ir, 0) = vmetr1*dror(ir) mass(ir) = r(ir) - srafac*srafac*vmetr1 end do do l = 1, lmaxd do ir = 7, irc hamf(ir, l) = real(l*l+l, kind=dp)/mass(ir)*dror(ir) + hamf(ir, 0) end do end do ! ====================================================================== ! LDA+U ! Account for potential shift in case of LDA+U (averaged over m) ! by adding the average WLDAUAV to the spherical part of the ! potential. if (idoldau==1 .and. lopt>=0) then s1 = real(lopt*lopt+lopt, kind=dp) do ir = 2, irc vmetr1 = (vm2z(ir)-e+wldauav*cutoff(ir))*r(ir) hamfldau(ir) = (vmetr1-2.0e0_dp*z)*dror(ir) end do do ir = 7, irc hamf(ir, lopt) = s1/mass(ir)*dror(ir) + hamfldau(ir) end do end if ! LDA+U ! ====================================================================== do ir = 2, irc mass(ir) = mass(ir)*dror(ir) end do do l = 0, lmaxd s1 = s(l) sm1 = s1 - 1.0e0_dp sp1 = s1 + 1.0e0_dp ! ---> loop over the number of kinks do ip = 1, ipan if (ip==1) then irs = 2 ire = ircut(1) ! ---> initial values vme = vm2z(2) - e vmefac = 1.0e0_dp - vme*srafac*srafac if (nsra==2 .and. z>0.0e0_dp) then a(-1) = 0.0e0_dp a(0) = 1.0e0_dp b(0) = cmplx(sm1*cvlight*cvlight/(2*z), 0.0e0_dp, kind=dp) do j = 1, 3 a(j) = (0.0e0_dp, 0.e0_dp) b(j) = (0.0e0_dp, 0.e0_dp) end do else a(0) = 0.0e0_dp b(0) = real(l, kind=dp)/vmefac a(1) = 1.0e0_dp do j = 2, 4 a(j) = (vme*vmefac*a(j-2)-2.0e0_dp*z*a(j-1))/real((j-1)*(j+2*l), kind=dp) b(j-1) = real(l+j-1, kind=dp)*a(j)/vmefac end do end if k = -4 ! ---> power series near origin do ir = 2, 6 pip0 = a(3) dpd0 = 3.0e0_dp*a(3) fip0 = b(3) dfd0 = 3.0e0_dp*b(3) do j = 2, 0, -1 pip0 = a(j) + pip0*r(ir) dpd0 = real(j, kind=dp)*a(j) + dpd0*r(ir) fip0 = b(j) + fip0*r(ir) dfd0 = real(j, kind=dp)*b(j) + dfd0*r(ir) end do pz(ir, l) = pip0 fz(ir, l) = fip0 dpdi(k) = dpd0*dror(ir) dfdi(k) = dfd0*dror(ir) k = k + 1 end do else ! ---> runge kutta step to restart algorithm irs = ircut(ip-1) + 1 ire = ircut(ip) irsp1 = irs + 1 pip0 = pz(irs, l) fip0 = fz(irs, l) drsp1 = dror(irs)*sp1 drsm1 = dror(irs)*sm1 dpdi(-4) = mass(irs)*fip0 - drsm1*pip0 dfdi(-4) = hamf(irs, l)*pip0 - drsp1*fip0 ! ---> first step - 4 point runge kutta with interpolation k1p = dpdi(-4) k1f = dfdi(-4) dror1 = (3.0e0_dp*dror(irs+3)-15.0e0_dp*dror(irs+2)+45.0e0_dp*dror(irsp1)+& 15.0e0_dp*dror(irs))/48.0e0_dp drsp1 = dror1*sp1 drsm1 = dror1*sm1 mass1 = (3.0e0_dp*mass(irs+3)-15.0e0_dp*mass(irs+2)+45.0e0_dp*mass(irsp1)+& 15.0e0_dp*mass(irs))/48.0e0_dp hamf1 = (3.0e0_dp*hamf(irs+3,l)-15.0e0_dp*hamf(irs+2,l)+ & 45.0e0_dp*hamf(irsp1,l)+15.0e0_dp*hamf(irs,l))/48.0e0_dp k2p = mass1*(fip0+0.5e0_dp*k1f) - drsm1*(pip0+0.5e0_dp*k1p) k2f = hamf1*(pip0+0.5e0_dp*k1p) - drsp1*(fip0+0.5e0_dp*k1f) k3p = mass1*(fip0+0.5e0_dp*k2f) - drsm1*(pip0+0.5e0_dp*k2p) k3f = hamf1*(pip0+0.5e0_dp*k2p) - drsp1*(fip0+0.5e0_dp*k2f) drsp1 = dror(irsp1)*sp1 drsm1 = dror(irsp1)*sm1 k4p = mass(irsp1)*(fip0+k3f) - drsm1*(pip0+k3p) k4f = hamf(irsp1, l)*(pip0+k3p) - drsp1*(fip0+k3f) pip0 = pip0 + (k1p+2.0e0_dp*(k2p+k3p)+k4p)/6.0e0_dp fip0 = fip0 + (k1f+2.0e0_dp*(k2f+k3f)+k4f)/6.0e0_dp pz(irsp1, l) = pip0 fz(irsp1, l) = fip0 dpdi(-3) = mass(irsp1)*fip0 - drsm1*pip0 dfdi(-3) = hamf(irsp1, l)*pip0 - drsp1*fip0 k = -2 ! ---> 4 point runge kutta with h = i+2 - i do ir = irs + 2, irs + 4 pip0 = pz(ir-2, l) fip0 = fz(ir-2, l) k1p = dpdi(k-2) k1f = dfdi(k-2) k2p = mass(ir-1)*(fip0+k1f) - drsm1*(pip0+k1p) k2f = hamf(ir-1, l)*(pip0+k1p) - drsp1*(fip0+k1f) k3p = mass(ir-1)*(fip0+k2f) - drsm1*(pip0+k2p) k3f = hamf(ir-1, l)*(pip0+k2p) - drsp1*(fip0+k2f) drsp1 = dror(ir)*sp1 drsm1 = dror(ir)*sm1 k4p = mass(ir)*(fip0+2.0e0_dp*k3f) - drsm1*(pip0+2.0e0_dp*k3p) k4f = hamf(ir, l)*(pip0+2.0e0_dp*k3p) - drsp1*(fip0+2.0e0_dp*k3f) pip0 = pip0 + (k1p+2.0e0_dp*(k2p+k3p)+k4p)/3.0e0_dp fip0 = fip0 + (k1f+2.0e0_dp*(k2f+k3f)+k4f)/3.0e0_dp pz(ir, l) = pip0 fz(ir, l) = fip0 dpdi(k) = mass(ir)*fip0 - drsm1*pip0 dfdi(k) = hamf(ir, l)*pip0 - drsp1*fip0 k = k + 1 end do end if do ir = irs + 5, ire drsp1 = dror(ir)*sp1 drsm1 = dror(ir)*sm1 ! ---> predictor : 5 point adams - bashforth pip1 = pip0 + (1901.0e0_dp*dpdi(0)-2774.0e0_dp*dpdi(-1)+ & 2616.0e0_dp*dpdi(-2)-1274.0e0_dp*dpdi(-3)+251.0e0_dp*dpdi(-4))/720.0e0_dp fip1 = fip0 + (1901.0e0_dp*dfdi(0)-2774.0e0_dp*dfdi(-1)+ & 2616.0e0_dp*dfdi(-2)-1274.0e0_dp*dfdi(-3)+251.0e0_dp*dfdi(-4))/720.0e0_dp dpdi(-4) = dpdi(-3) dpdi(-3) = dpdi(-2) dpdi(-2) = dpdi(-1) dpdi(-1) = dpdi(0) dfdi(-4) = dfdi(-3) dfdi(-3) = dfdi(-2) dfdi(-2) = dfdi(-1) dfdi(-1) = dfdi(0) dpdi(0) = mass(ir)*fip1 - drsm1*pip1 dfdi(0) = hamf(ir, l)*pip1 - drsp1*fip1 ! ---> corrector : 5 point adams - moulton pip0 = pip0 + (251.0e0_dp*dpdi(0)+646.0e0_dp*dpdi(-1) & -264.0e0_dp*dpdi(-2)+106.0e0_dp*dpdi(-3)-19.0e0_dp*dpdi(-4))/720.0e0_dp fip0 = fip0 + (251.0e0_dp*dfdi(0)+646.0e0_dp*dfdi(-1) & -264.0e0_dp*dfdi(-2)+106.0e0_dp*dfdi(-3)-19.0e0_dp*dfdi(-4))/720.0e0_dp pz(ir, l) = pip0 fz(ir, l) = fip0 dpdi(0) = mass(ir)*fip0 - drsm1*pip0 dfdi(0) = hamf(ir, l)*pip0 - drsp1*fip0 end do ! ---> remember that the r - mesh contains the kinks two times ! store the values of pz and fz to restart the algorithm if (ip/=ipan) then pz(ire+1, l) = pip0 fz(ire+1, l) = fip0 end if end do ! ---> logarithmic derivate of real wavefunction ( r**s *pz / r) dlogdp(l) = (dpdi(0)/(pip0*dror(irc))+sm1)/r(irc) end do end subroutine regsol end module mod_regsol