LCOV - code coverage report
Current view: top level - force - force_a12_lv2.f90 (source / functions) Hit Total Coverage
Test: FLEUR test coverage Lines: 96 101 95.0 %
Date: 2024-05-05 04:27:49 Functions: 1 1 100.0 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------
       2             : ! Copyright (c) 2020 Peter Grünberg Institut, Forschungszentrum Jülich, Germany
       3             : ! This file is part of FLEUR and available as free software under the conditions
       4             : ! of the MIT license as expressed in the LICENSE file in more detail.
       5             : !--------------------------------------------------------------------------------
       6             : 
       7             : MODULE m_force_a12_lv2
       8             :    USE m_constants
       9             :    USE m_ylm
      10             :    USE m_sphbes
      11             :    USE m_gaunt
      12             :    USE m_types_mat
      13             :    !------------------------------------------------------------------------------
      14             :    ! Calculates the surface integral due to kinetic energy terms according to
      15             :    ! the last two lines of equation (14) in 
      16             :    ! 
      17             :    ! Klüppelberg et al., PRB 91 035105 (2015).
      18             :    ! 
      19             :    ! Klueppelberg (force level 2) 
      20             :    !------------------------------------------------------------------------------
      21             : 
      22             :    IMPLICIT NONE
      23             : 
      24             : CONTAINS
      25           2 :    SUBROUTINE force_a12_lv2(jsp,jspd,nobd,neigd,ntypd,ntype,natd,nbasfcn,nop,&
      26           2 :                             nvd,lmaxd,omtil,nv,neq,k1,k2,k3,invarind,invarop,&
      27           2 :                             invtab,mrot,ngopr,amat,bmat,eig,rmt,taual,we,bkpt,&
      28           2 :                             zMat,f_a12,force )
      29             : 
      30             :       INTEGER, INTENT (IN) :: jsp,jspd,nobd,neigd,ntypd,ntype,natd
      31             :       INTEGER, INTENT (IN) :: nbasfcn,nop,nvd,lmaxd
      32             :       REAL   , INTENT (IN) :: omtil
      33             : 
      34             :       INTEGER, INTENT (IN) :: nv(jspd),neq(ntypd)
      35             :       INTEGER, INTENT (IN) :: k1(nvd,jspd),k2(nvd,jspd),k3(nvd,jspd)
      36             :       INTEGER, INTENT (IN) :: invarind(natd),invarop(natd,nop)
      37             :       INTEGER, INTENT (IN) :: invtab(nop),mrot(3,3,nop),ngopr(natd)
      38             :       REAL   , INTENT (IN) :: amat(3,3),bmat(3,3),eig(neigd),rmt(ntypd)
      39             :       REAL   , INTENT (IN) :: taual(3,natd),we(nobd),bkpt(3)
      40             :       TYPE(t_mat), INTENT(IN)             :: zMat
      41             :       COMPLEX, INTENT (INOUT) :: f_a12(3,ntypd)
      42             :       REAL   , INTENT (INOUT) :: force(3,ntypd,jspd)
      43             : 
      44             :       INTEGER :: lmax,kn,iband,iatom,itype,ieq,l,m,lm,t,lp,mp,lmp,it,is
      45             :       INTEGER :: isinv,i
      46             :       REAL    :: normsq,r,r2vol
      47             :       COMPLEX :: img,noband,fpil
      48             : 
      49           2 :       COMPLEX :: force_a12(3,ntypd),gv(3),Ygaunt(3)
      50             :       COMPLEX :: coeff(3,-1:1),gvint(3),vecsum(3),starsum(3)
      51           2 :       REAL   , ALLOCATABLE :: bsl(:,:,:),G(:,:),kG(:,:),kGreal(:,:)
      52           2 :       REAL   , ALLOCATABLE :: kineticfactor(:,:)
      53           2 :       COMPLEX, ALLOCATABLE :: ylm(:,:),ppw(:,:),fpw(:,:),expf(:,:)
      54           2 :       REAL :: zr(nbasfcn,nobd)
      55           2 :       COMPLEX :: zc(nbasfcn,nobd)
      56             : 
      57           2 :       CALL timestart("Force level 2")
      58             : 
      59           2 :       IF (zMat%l_real) THEN
      60      126329 :         zr=zMat%data_r 
      61             :       ELSE
      62           0 :         zc=zMat%data_c 
      63             :       END IF
      64             : 
      65           2 :       lmax = 2*lmaxd
      66           2 :       img = cmplx(0.0,1.0)
      67             : 
      68          16 :       ALLOCATE ( bsl(0:lmax,nvd,ntypd),ylm((lmax+1)**2,nvd) )
      69          12 :       ALLOCATE ( ppw(nobd,(lmax+1)**2),fpw(nobd,(lmax+1)**2) )
      70          16 :       ALLOCATE ( G(3,nvd),kG(3,nvd),kGreal(3,nvd),expf(nvd,natd) )
      71           8 :       ALLOCATE ( kineticfactor(nobd,nvd) )
      72             : 
      73           2 :       coeff(:, :) =   cmplx(0.0,0.0)
      74           2 :       coeff(1,-1) =     sqrt(tpi_const/3.)
      75           2 :       coeff(1, 1) =    -sqrt(tpi_const/3.)
      76           2 :       coeff(2,-1) = img*sqrt(tpi_const/3.)
      77           2 :       coeff(2, 1) = img*sqrt(tpi_const/3.)
      78           2 :       coeff(3, 0) =  sqrt(2.*tpi_const/3.)
      79             : 
      80             :       ! Loop over plane waves
      81        2445 :       DO kn = 1,nv(jsp)
      82        2443 :          G(1,kn) = k1(kn,jsp)
      83        2443 :          G(2,kn) = k2(kn,jsp)
      84        2443 :          G(3,kn) = k3(kn,jsp)
      85             : 
      86        9772 :          kG(:,kn) = bkpt(:) + G(:,kn)
      87       39088 :          kGreal(:,kn) = matmul(kG(:,kn),bmat)
      88             : 
      89             :          ! This is only useable using the Laplacian for kinetic energy
      90        9772 :          normsq = dot_product(kGreal(:,kn),kGreal(:,kn))
      91      127036 :          DO iband = 1,nobd
      92      127036 :             kineticfactor(iband,kn) = 0.5*normsq - eig(iband)
      93             :          END DO ! iband
      94             : 
      95        2443 :          CALL ylm4(lmax,kGreal(:,kn),ylm(:,kn))
      96        2443 :          iatom = 1
      97        9774 :          DO itype = 1,ntype
      98        7329 :             r = sqrt(normsq)*rmt(itype)
      99             : 
     100        7329 :             CALL sphbes(lmax,r,bsl(:,kn,itype))
     101       39088 :             DO ieq = 1,neq(itype)
     102      117264 :                expf(kn,iatom) = exp(tpi_const*img*dot_product(kG(:,kn),taual(:,iatom)))
     103             : 
     104       36645 :                iatom = iatom + 1
     105             :             END DO ! ieq
     106             :          END DO ! itype
     107             :       END DO ! kn
     108             : 
     109          26 :       force_a12 = 0.0
     110             : 
     111           2 :       iatom = 1
     112           8 :       DO itype = 1,ntype
     113           6 :          r2vol = rmt(itype)**2/omtil
     114          30 :          DO ieq = 1,neq(itype)
     115             : 
     116          24 :             gv  = 0.0
     117      360696 :             ppw = 0.0
     118      360696 :             fpw = 0.0
     119             : 
     120         408 :             DO l = 0,lmax-1 ! (arrays run to lmax, l+1 can only be supported til lmax-1)
     121         384 :                fpil = 2.*tpi_const*img**l
     122             :                ! Calculate ppw and fpw
     123      469440 :                DO kn = 1,nv(jsp)
     124     7973952 :                   DO m = -l,l
     125     7504896 :                      lm = l*(l+1) + m + 1
     126     7504896 :                      noband = expf(kn,iatom)*conjg(ylm(lm,kn))*bsl(l,kn,itype) * fpil
     127   390723648 :                      DO iband = 1,nobd
     128   390254592 :                         IF (zMat%l_real) THEN
     129   382749696 :                            ppw(iband,lm) = ppw(iband,lm) + zr(kn,iband) * noband
     130   382749696 :                            IF (l.gt.0) CYCLE
     131             :                            fpw(iband,lm) = fpw(iband,lm) + zr(kn,iband) * noband * &
     132     1495116 :                                                            kineticfactor(iband,kn)
     133             :                         ELSE
     134           0 :                            ppw(iband,lm) = ppw(iband,lm) + zc(kn,iband) * noband
     135           0 :                            IF (l.gt.0) CYCLE
     136             :                            fpw(iband,lm) = fpw(iband,lm) + zc(kn,iband) * noband * &
     137           0 :                                                            kineticfactor(iband,kn)                   
     138             :                         END IF
     139             :                      END DO ! iband
     140             :                   END DO ! m
     141             :    
     142             :                   ! If ppw is used with l, one needs fpw with l-1 (already calculated) 
     143             :                   ! and l+1 (calculated now)
     144     8912448 :                   DO m = -l-1,l+1
     145     8443008 :                      lm = (l+1)*(l+2) + m + 1
     146     8443008 :                      noband =expf(kn,iatom)*conjg(ylm(lm,kn))*bsl(l+1,kn,itype) * fpil * img
     147   439505472 :                      DO iband = 1,nobd
     148   439036416 :                         IF (zMat%l_real) THEN
     149             :                            fpw(iband,lm) = fpw(iband,lm) + zr(kn,iband) * noband * &
     150   430593408 :                                                            kineticfactor(iband,kn)
     151             :                         ELSE
     152             :                            fpw(iband,lm) = fpw(iband,lm) + zc(kn,iband) * noband * &
     153           0 :                                                            kineticfactor(iband,kn)
     154             :                         END IF
     155             :                      END DO ! iband
     156             :                   END DO ! m
     157             :                END DO ! kn
     158             : 
     159             :                ! Calculate forces
     160        6552 :                DO m = -l,l
     161        6144 :                   lm = l*(l+1) + m + 1
     162       18792 :                   DO lp = abs(l-1),l+1,2
     163       55200 :                      DO t = -1,1
     164       36792 :                         mp = m-t
     165       36792 :                         IF (lp.lt.abs(mp)) CYCLE
     166       34632 :                         lmp = lp*(lp+1) + mp + 1
     167      138528 :                         Ygaunt(:) = gaunt2(l,1,lp,m,t,mp,lmax)*coeff(:,t)
     168     1813128 :                         DO iband = 1,nobd
     169             :                            gv(:) = gv(:) + we(iband) * r2vol * Ygaunt(:) * &
     170     7101720 :                                            conjg(ppw(iband,lm)) * fpw(iband,lmp)
     171             :                         END DO ! iband
     172             :                      END DO ! t
     173             :                   END DO ! lp
     174             :                END DO ! m
     175             :             END DO ! lmax
     176             : 
     177             :             ! starsumgedoens
     178             :             ! k summation is only on IBZ. Expansion to FBZ can be achieved by
     179             :             ! applying the rotation of the k-points to the atomic positions of
     180             :             ! equivalent atoms.
     181             :             ! Until now, the forces for one k-point are calculated for one
     182             :             ! specific atom, not considering such a rotation. To do so, the
     183             :             ! resulting forces have to be rotated back to the representative
     184             :             ! atom. This is done in the next 6 lines.
     185             : 
     186         672 :             vecsum = matmul(bmat,gv)/tpi_const/neq(itype)
     187             : 
     188         600 :             gvint = matmul(mrot(:,:,1),vecsum)
     189             : 
     190          24 :             vecsum = 0
     191             : 
     192          48 :             DO it = 1,invarind(iatom) ! loop over invariant operations
     193          24 :                is = invarop(iatom,it)
     194          24 :                isinv = invtab(is)
     195             : 
     196         696 :                vecsum = vecsum + matmul(mrot(:,:,isinv),gvint(:))
     197             : 
     198             :             END DO ! it
     199             : 
     200          24 :             is = ngopr(iatom)
     201          24 :             it = invtab(is)
     202             : 
     203         600 :             vecsum = matmul(mrot(:,:,is),vecsum)
     204             : 
     205         600 :             starsum = matmul(amat,vecsum)
     206          96 :             force_a12(:,itype) = force_a12(:,itype) + real(starsum(:))/invarind(iatom)
     207             : 
     208          30 :             iatom = iatom + 1
     209             :          END DO ! ieq
     210          24 :          force(:,itype,jsp) = force(:,itype,jsp) + force_a12(:,itype)
     211          26 :          f_a12(:,itype)     = f_a12(:,itype)     + force_a12(:,itype)
     212             :       END DO ! itype
     213             : 
     214           2 :       DEALLOCATE ( bsl,ylm,ppw,fpw )
     215           2 :       DEALLOCATE ( G,kG,kGreal,expf,kineticfactor )
     216             : 
     217           2 :       CALL timestop("Force level 2")
     218             : 
     219           2 :    END SUBROUTINE force_a12_lv2
     220             : END MODULE m_force_a12_lv2

Generated by: LCOV version 1.14