! ! Copyright (C) 2001 PWSCF group ! This file is distributed under the terms of the ! GNU General Public License. See the file `License' ! in the root directory of the present distribution, ! or http://www.gnu.org/copyleft/gpl.txt . ! !----------------------------------------------------------------------- subroutine dylmr2 (nylm, ngy, g, gg, dylm, ipol) !----------------------------------------------------------------------- !! Compute \partial Y_lm(G) \over \partial (G)_ipol !! using simple numerical derivation (SdG) !! The spherical harmonics are calculated in ylmr2 ! USE upf_kinds, ONLY : DP implicit none ! integer :: nylm !! input: number of spherical harmonics integer :: ngy !! input: the number of g vectors to compute integer :: ipol !! input: desired polarization real(DP) :: g(3,ngy) !! input: the coordinates of g vectors real(DP) :: gg (ngy) !! input: the moduli of g vectors real(DP) :: dylm (ngy, nylm) !! output: the spherical harmonics derivatives ! ! ... local variables ! integer :: ig, lm ! counter on g vectors ! counter on l,m component real(DP), parameter :: delta = 1.d-6 real(DP), allocatable :: dg (:), dgi (:), gx (:,:), ggx (:), ylmaux (:,:) ! dg is the finite increment for numerical derivation: ! dg = delta |G| = delta * sqrt(gg) ! dgi= 1 /(delta * sqrt(gg)) ! gx = g +/- dg ! ggx = gx^2 ! allocate ( gx(3,ngy), ggx(ngy), dg(ngy), dgi(ngy), ylmaux(ngy,nylm) ) !$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(ig) do ig = 1, ngy dg (ig) = delta * sqrt (gg (ig) ) if (gg (ig) .gt. 1.d-9) then dgi (ig) = 1.d0 / dg (ig) else dgi (ig) = 0.d0 endif enddo !$OMP END PARALLEL DO call dcopy (3 * ngy, g, 1, gx, 1) !$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(ig) do ig = 1, ngy gx (ipol, ig) = g (ipol, ig) + dg (ig) ggx (ig) = gx (1, ig) * gx (1, ig) + & gx (2, ig) * gx (2, ig) + & gx (3, ig) * gx (3, ig) enddo !$OMP END PARALLEL DO call ylmr2 (nylm, ngy, gx, ggx, dylm) !$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(ig) do ig = 1, ngy gx (ipol, ig) = g (ipol, ig) - dg (ig) ggx (ig) = gx (1, ig) * gx (1, ig) + & gx (2, ig) * gx (2, ig) + & gx (3, ig) * gx (3, ig) enddo !$OMP END PARALLEL DO call ylmr2 (nylm, ngy, gx, ggx, ylmaux) call daxpy (ngy * nylm, - 1.d0, ylmaux, 1, dylm, 1) do lm = 1, nylm !$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(ig) do ig = 1, ngy dylm (ig, lm) = dylm (ig, lm) * 0.5d0 * dgi (ig) enddo !$OMP END PARALLEL DO enddo deallocate ( gx, ggx, dg, dgi, ylmaux ) return end subroutine dylmr2