LCOV - code coverage report
Current view: top level - src/66_nonlocal - m_opernld_ylm.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 42.2 % 509 215
Test Date: 2026-09-21 13:49:52 Functions: 100.0 % 1 1

            Line data    Source code
       1              : !!****m* ABINIT/m_opernld_ylm
       2              : !! NAME
       3              : !!  m_opernld_ylm
       4              : !!
       5              : !! FUNCTION
       6              : !!
       7              : !!
       8              : !! COPYRIGHT
       9              : !!  Copyright (C) 2008-2026 ABINIT group (MT)
      10              : !!  This file is distributed under the terms of the
      11              : !!  GNU General Public License, see ~abinit/COPYING
      12              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      13              : !!
      14              : !! SOURCE
      15              : 
      16              : #if defined HAVE_CONFIG_H
      17              : #include "config.h"
      18              : #endif
      19              : 
      20              : #include "abi_common.h"
      21              : 
      22              : module m_opernld_ylm
      23              : 
      24              :  use defs_basis
      25              :  use m_errors
      26              :  use m_abicore
      27              : 
      28              :  implicit none
      29              : 
      30              :  private
      31              : !!***
      32              : 
      33              :  public :: opernld_ylm
      34              : !!***
      35              : 
      36              : contains
      37              : !!***
      38              : 
      39              : !!****f* ABINIT/opernld_ylm
      40              : !! NAME
      41              : !! opernld_ylm
      42              : !!
      43              : !! FUNCTION
      44              : !! * Operate with the non-local part of the hamiltonian,
      45              : !!   in order to get contributions to energy/forces/stress/dyn.matrix/elst tens.
      46              : !!   from projected scalars
      47              : !! * Operate with the non-local projectors and the overlap matrix Sij
      48              : !!   in order to get contributions to <c|S|c>
      49              : !!   from projected scalars
      50              : !!
      51              : !! INPUTS
      52              : !!  choice=chooses possible output
      53              : !!  cplex=1 if <p_lmn|c> scalars are real (equivalent to istwfk>1)
      54              : !!        2 if <p_lmn|c> scalars are complex
      55              : !!  cplex_fac=1 if gxfac scalars are real, 2 if gxfac scalars are complex
      56              : !!  d2gxdt(cplex,nd2gxdt,nlmn,nincat,nspinor)=2nd gradients of projected scalars
      57              : !!  dgxdt(cplex,ndgxdt,nlmn,nincat,nspinor)=gradients of projected scalars
      58              : !!  dgxdtfac(cplex_fac,ndgxdtfac,nlmn,nincat,nspinor)=gradients of reduced projected scalars
      59              : !!                                                    related to Vnl (NL operator)
      60              : !!  dgxdtfac_sij(cplex_fac,ndgxdtfac,nlmn,nincat,nspinor)=gradients of reduced projected scalars
      61              : !!                                                        related to Sij (overlap)
      62              : !!  gx(cplex,nlmn,nincat,nspinor)= projected scalars
      63              : !!  gxfac(cplex_fac,nlmn,nincat,nspinor)= reduced projected scalars related to Vnl (NL operator)
      64              : !!  gxfac_sij(cplex,nlmn,nincat,nspinor)= reduced projected scalars related to Sij (overlap)
      65              : !!  ia3=gives the absolute number of the first atom in the subset presently treated
      66              : !!  natom=number of atoms in cell
      67              : !!  nd2gxdt=second dimension of d2gxdt
      68              : !!  ndgxdt=second dimension of dgxdt
      69              : !!  ndgxdtfac=second dimension of dgxdtfac
      70              : !!  nincat=number of atoms in the subset here treated
      71              : !!  nlmn=number of (l,m,n) numbers for current type of atom
      72              : !!  nnlout=dimension of enlout
      73              : !!  nspinor=number of spinorial components of the wavefunctions (on current proc)
      74              : !!  paw_opt= define the nonlocal operator concerned with:
      75              : !!           paw_opt=0 : Norm-conserving Vnl (use of Kleinman-Bylander ener.)
      76              : !!           paw_opt=1 : PAW nonlocal part of H (use of Dij coeffs)
      77              : !!           paw_opt=2 : PAW: (Vnl-lambda.Sij) (Sij=overlap matrix)
      78              : !!           paw_opt=3 : PAW overlap matrix (Sij)
      79              : !!           paw_opt=4 : both PAW nonlocal part of H (Dij) and overlap matrix (Sij)
      80              : !!
      81              : !! OUTPUT
      82              : !!  (see side effects)
      83              : !!
      84              : !! SIDE EFFECTS
      85              : !! --If (paw_opt==0, 1 or 2)
      86              : !!    enlout(nnlout)= contribution to the non-local part of the following properties:
      87              : !!      if choice=1 : enlout(1)             -> the energy
      88              : !!      if choice=2 : enlout(3*natom)       -> 1st deriv. of energy wrt atm. pos (forces)
      89              : !!      if choice=3 : enlout(6)             -> 1st deriv. of energy wrt strain (stresses)
      90              : !!      if choice=4 : enlout(6*natom)       -> 2nd deriv. of energy wrt 2 atm. pos (dyn. mat.)
      91              : !!      if choice=23: enlout(6+3*natom)     -> 1st deriv. of energy wrt atm. pos (forces) and
      92              : !!                                             1st deriv. of energy wrt strain (stresses)
      93              : !!      if choice=24: enlout(9*natom)       -> 1st deriv. of energy wrt atm. pos (forces) and
      94              : !!                                             2nd deriv. of energy wrt 2 atm. pos (dyn. mat.)
      95              : !!      if choice=5 : enlout(3)             -> 1st deriv. of energy wrt k
      96              : !!      if choice=53: enlout(3)             -> 1st deriv. (twist) of energy wrt k
      97              : !!      if choice=54: enlout(18*natom)      -> 2nd deriv. of energy wrt atm. pos and right k (Born eff. charge)
      98              : !!      if choice=55: enlout(36)            -> 2nd deriv. of energy wrt strain and right k (piezoelastic tensor)
      99              : !!      if choice=6 : enlout(36+18*natom)   -> 2nd deriv. of energy wrt 2 strains (elast. tensor) and
     100              : !!                                             2nd deriv. of energy wrt to atm. pos and strain (internal strain)
     101              : !!      if choice=8 : enlout(6)             -> 2nd deriv. of energy wrt 2 k
     102              : !!      if choice=81: enlout(18)            -> 2nd deriv. of energy wrt k and right k
     103              : !! --If (paw_opt==3)
     104              : !!      if choice=1 : enlout(1)             -> contribution to <c|S|c> (note: not including <c|c>)
     105              : !!      if choice=2 : enlout(3*natom)       -> contribution to <c|dS/d_atm.pos|c>
     106              : !!      if choice=53: enlout(3)             -> 1st deriv. (twist) of energy wrt k
     107              : !!      if choice=54: enlout(18*natom)      -> 2nd deriv. of energy wrt atm. pos and right k (Born eff. charge)
     108              : !!      if choice=55: enlout(36)            -> 2nd deriv. of energy wrt strain and right k (piezoelastic tensor)
     109              : !!      if choice=8 : enlout(6)             -> 2nd deriv. of energy wrt 2 k
     110              : !!      if choice=81: enlout(18)            -> 2nd deriv. of energy wrt k and right k
     111              : !! --If (paw_opt==4)
     112              : !!      not available
     113              : !!
     114              : !! NOTES
     115              : !! Operate for one type of atom, and within this given type of atom,
     116              : !! for a subset of at most nincat atoms.
     117              : !!
     118              : !! SOURCE
     119              : 
     120       738502 : subroutine opernld_ylm(choice,cplex,cplex_fac,ddkk,dgxdt,dgxdtfac,dgxdtfac_sij,d2gxdt,&
     121       738502 : &                      enlk,enlout,fnlk,gx,gxfac,gxfac_sij,ia3,natom,ndat_left,nd2gxdt,ndgxdt,&
     122              : &                      ndgxdtfac,nincat,nlmn,nnlout,nspinor,paw_opt,strnlk,&
     123              : &                      enlout_im)
     124              : 
     125              : !Arguments ------------------------------------
     126              : !scalars
     127              :  integer,intent(in) :: choice,cplex,cplex_fac,ia3,natom,nd2gxdt,ndgxdt
     128              :  integer,intent(in) :: ndgxdtfac,nincat,nlmn,nnlout,nspinor,paw_opt
     129              :  integer,intent(in) :: ndat_left
     130              :  real(dp),intent(inout) :: enlk
     131              : !arrays
     132              :  real(dp),intent(in) :: d2gxdt(cplex,nd2gxdt,nlmn,nincat,nspinor)
     133              :  real(dp),intent(in) :: dgxdt(cplex,ndgxdt,nlmn,nincat,nspinor)
     134              :  real(dp),intent(in) :: dgxdtfac(cplex_fac,ndgxdtfac,nlmn,nincat,nspinor)
     135              :  real(dp),intent(in) :: dgxdtfac_sij(cplex,ndgxdtfac,nlmn,nincat,nspinor*(paw_opt/3))
     136              :  real(dp),intent(in) :: gx(cplex,nlmn,nincat,nspinor*ndat_left),gxfac(cplex_fac,nlmn,nincat,nspinor)
     137              :  real(dp),intent(in) :: gxfac_sij(cplex,nlmn,nincat,nspinor*(paw_opt/3))
     138              :  real(dp),intent(inout) :: ddkk(6),enlout(nnlout*ndat_left),fnlk(3*natom),strnlk(6)
     139              :  real(dp),intent(inout),optional :: enlout_im(nnlout*ndat_left)
     140              : 
     141              : !Local variables-------------------------------
     142              : !scalars
     143              :  integer :: ia,iashift,idat_left,ilmn,iplex,ishift,ispinor,mu,mua,mua1,mua2,mub,mushift,mut,muu
     144              :  integer :: nu,nushift
     145              :  real(dp) :: dummy
     146              : !arrays
     147              :  integer,parameter :: alpha(6)=(/1,2,3,3,3,2/),beta(6)=(/1,2,3,2,1,1/)
     148              :  integer,parameter :: gamma(3,3)=reshape((/1,6,5,6,2,4,5,4,3/),(/3,3/))
     149              :  integer,parameter :: twist_dir(6)=(/2,3,3,1,1,2/)
     150      1477004 :  real(dp) :: d2gx(cplex),enlj(6*cplex),gxfacj(cplex)
     151       738502 :  real(dp),allocatable :: enljj(:)
     152       738502 :  complex(dp),allocatable :: cft(:,:), cfu(:,:)
     153              : ! *************************************************************************
     154              : 
     155       738502 :  ABI_CHECK(cplex_fac>=cplex,'BUG: invalid cplex_fac<cplex!')
     156              : 
     157       738502 :  if (paw_opt==0.or.paw_opt==1.or.paw_opt==2) then
     158              : 
     159              : !  ============== Accumulate the non-local energy ===============
     160       473638 :    if (choice==1) then
     161            0 :      if (present(enlout_im).and.cplex==2) then ! cplex=cplex_fac=2
     162            0 :        do idat_left=1,ndat_left
     163            0 :          do ispinor=1,nspinor
     164            0 :            do ia=1,nincat
     165            0 :              do ilmn=1,nlmn
     166            0 :                enlout   (idat_left)=enlout   (idat_left)+gxfac(1,ilmn,ia,ispinor)*gx(1,ilmn,ia,ispinor+(idat_left-1)*nspinor)
     167            0 :                enlout   (idat_left)=enlout   (idat_left)+gxfac(2,ilmn,ia,ispinor)*gx(2,ilmn,ia,ispinor+(idat_left-1)*nspinor)
     168            0 :                enlout_im(idat_left)=enlout_im(idat_left)+gxfac(2,ilmn,ia,ispinor)*gx(1,ilmn,ia,ispinor+(idat_left-1)*nspinor)
     169            0 :                enlout_im(idat_left)=enlout_im(idat_left)-gxfac(1,ilmn,ia,ispinor)*gx(2,ilmn,ia,ispinor+(idat_left-1)*nspinor)
     170              :              end do
     171              :            end do
     172              :          end do
     173              :        end do
     174            0 :      else if (present(enlout_im).and.cplex_fac==2) then ! cplex=1,cplex_fac=2
     175            0 :        do idat_left=1,ndat_left
     176            0 :          do ispinor=1,nspinor
     177            0 :            do ia=1,nincat
     178            0 :              do ilmn=1,nlmn
     179            0 :                enlout   (idat_left)=enlout   (idat_left)+gxfac(1,ilmn,ia,ispinor)*gx(1,ilmn,ia,ispinor+(idat_left-1)*nspinor)
     180            0 :                enlout_im(idat_left)=enlout_im(idat_left)+gxfac(2,ilmn,ia,ispinor)*gx(1,ilmn,ia,ispinor+(idat_left-1)*nspinor)
     181              :              end do
     182              :            end do
     183              :          end do
     184              :        end do
     185              :      else ! only the real part is needed or the imaginary part is zero
     186            0 :        do idat_left=1,ndat_left
     187            0 :          do ispinor=1,nspinor
     188            0 :            do ia=1,nincat
     189            0 :              do ilmn=1,nlmn
     190            0 :                do iplex=1,cplex
     191            0 :                  enlout(idat_left)=enlout(idat_left)+gxfac(iplex,ilmn,ia,ispinor)*gx(iplex,ilmn,ia,ispinor+(idat_left-1)*nspinor)
     192              :                end do
     193              :              end do
     194              :            end do
     195              :          end do
     196              :        end do
     197              :      end if
     198              :    end if
     199              : 
     200              : !  ============ Accumulate the forces contributions =============
     201       473638 :    if (choice==2.or.choice==23.or.choice==24) then
     202       381305 :      ishift=0;if (choice==23) ishift=6
     203       828268 :      do ispinor=1,nspinor
     204      1950523 :        do ia=1,nincat
     205      4119688 :          enlj(1:3)=zero
     206      1029922 :          iashift=3*(ia+ia3-2)+ishift
     207     11176397 :          do ilmn=1,nlmn
     208     41615822 :            do mu=1,3
     209              :              dummy = zero  ! Dummy needed here to get the correct forces with intel -O3
     210     80196027 :              do iplex=1,cplex
     211              :                !enlj(mu)=enlj(mu)+gxfac(iplex,ilmn,ia,ispinor)*dgxdt(iplex,mu+ishift,ilmn,ia,ispinor)
     212     80196027 :                dummy=dummy+gxfac(iplex,ilmn,ia,ispinor)*dgxdt(iplex,mu+ishift,ilmn,ia,ispinor)
     213              :              end do
     214     40585900 :              enlj(mu)=enlj(mu)+dummy
     215              :            end do
     216              :          end do
     217      4566651 :          enlout(iashift+1:iashift+3)=enlout(iashift+1:iashift+3)+two*enlj(1:3)
     218              :        end do
     219              :      end do
     220              :    end if
     221              : 
     222              : !  ======== Accumulate the stress tensor contributions ==========
     223       473638 :    if (choice==3.or.choice==23) then
     224       760606 :      enlj(1:6)=zero
     225       228414 :      do ispinor=1,nspinor
     226       411979 :        do ia=1,nincat
     227      2697174 :          do ilmn=1,nlmn
     228      7117731 :            gxfacj(1:cplex)=gxfac(1:cplex,ilmn,ia,ispinor)
     229      7117731 :            do iplex=1,cplex
     230      7117731 :              enlk=enlk+gxfacj(iplex)*gx(iplex,ilmn,ia,ispinor)
     231              :            end do
     232     16940536 :            do mu=1,6
     233     45100239 :              do iplex=1,cplex
     234     42706386 :                enlj(mu)=enlj(mu)+gxfacj(iplex)*dgxdt(iplex,mu,ilmn,ia,ispinor)
     235              :              end do
     236              :            end do
     237              :          end do
     238              :        end do
     239              :      end do
     240       760606 :      enlout(1:6)=enlout(1:6)+two*enlj(1:6)
     241              :    end if
     242              : 
     243              : !  ====== Accumulate the dynamical matrix contributions =========
     244       473638 :    if (choice==4.or.choice==24) then
     245        42584 :      ishift=0;if (choice==24) ishift=3*natom
     246        85232 :      do ispinor=1,nspinor
     247       130920 :        do ia=1,nincat
     248       319816 :          enlj(1:6)=zero
     249        45688 :          iashift=6*(ia+ia3-2)+ishift
     250       514024 :          do ilmn=1,nlmn
     251      3324040 :            do mu=1,6
     252      2810016 :              mua=alpha(mu);mub=beta(mu)
     253      8898384 :              do iplex=1,cplex
     254              :                enlj(mu)=enlj(mu)+gxfac(iplex,ilmn,ia,ispinor)*d2gxdt(iplex,mu,ilmn,ia,ispinor)&
     255      8430048 : &               +dgxdtfac(iplex,mub,ilmn,ia,ispinor)*dgxdt(iplex,mua,ilmn,ia,ispinor)
     256              :              end do
     257              :            end do
     258              :          end do
     259       362464 :          enlout(iashift+1:iashift+6)=enlout(iashift+1:iashift+6)+two*enlj(1:6)
     260              :        end do
     261              :      end do
     262              :    end if
     263              : 
     264              : !  ======== Accumulate the contributions of derivatives of E wrt to k ==========
     265       473638 :    if (choice==5) then
     266         4608 :      enlj(1:3)=zero
     267         2304 :      do ispinor=1,nspinor
     268         3456 :        do ia=1,nincat
     269         2304 :          if(cplex==2)then
     270        10368 :            do ilmn=1,nlmn
     271        38016 :              do mu=1,3
     272        92160 :                do iplex=1,cplex
     273        82944 :                  enlj(mu)=enlj(mu)+gxfac(iplex,ilmn,ia,ispinor)*dgxdt(iplex,mu,ilmn,ia,ispinor)
     274              :                end do
     275              :              end do
     276              :            end do
     277              : !        If cplex=1, dgxdt is pure imaginary; thus there is no contribution
     278            0 :          else if (cplex_fac==2) then
     279            0 :            do ilmn=1,nlmn
     280            0 :              do mu=1,3
     281            0 :                enlj(mu)=enlj(mu)+gxfac(2,ilmn,ia,ispinor)*dgxdt(1,mu,ilmn,ia,ispinor)
     282              :              end do
     283              :            end do
     284              :          end if
     285              :        end do
     286              :      end do
     287         4608 :      enlout(1:3)=enlout(1:3)+two*enlj(1:3)
     288              :    end if
     289              : 
     290              : !  ======== Accumulate the contributions of partial derivatives of E wrt to k ==========
     291              : !  Choice 51: right derivative wrt to k ; Choice 52: left derivative wrt to k
     292       473638 :    if (choice==51.or.choice==52) then
     293            0 :      enlj(1:6)=zero
     294            0 :      do ispinor=1,nspinor
     295            0 :        do ia=1,nincat
     296            0 :          if(cplex==2)then
     297            0 :            do ilmn=1,nlmn
     298            0 :              do mu=1,3
     299              :                enlj(2*mu-1)=enlj(2*mu-1)+gxfac(1,ilmn,ia,ispinor)*dgxdt(1,mu,ilmn,ia,ispinor) &
     300            0 : &               +gxfac(2,ilmn,ia,ispinor)*dgxdt(2,mu,ilmn,ia,ispinor)
     301              :                enlj(2*mu  )=enlj(2*mu  )+gxfac(1,ilmn,ia,ispinor)*dgxdt(2,mu,ilmn,ia,ispinor) &
     302            0 : &               -gxfac(2,ilmn,ia,ispinor)*dgxdt(1,mu,ilmn,ia,ispinor)
     303              :              end do
     304              :            end do
     305            0 :          else if (cplex_fac==2) then
     306            0 :            do ilmn=1,nlmn
     307            0 :              do mu=1,3
     308            0 :                enlj(2*mu-1)=enlj(2*mu-1)+gxfac(2,ilmn,ia,ispinor)*dgxdt(1,mu,ilmn,ia,ispinor)
     309            0 :                enlj(2*mu  )=enlj(2*mu  )+gxfac(1,ilmn,ia,ispinor)*dgxdt(1,mu,ilmn,ia,ispinor)
     310              :              end do
     311              :            end do
     312            0 :          else if (cplex_fac==1) then
     313            0 :            do ilmn=1,nlmn
     314            0 :              do mu=1,3
     315            0 :                enlj(2*mu  )=enlj(2*mu  )+gxfac(1,ilmn,ia,ispinor)*dgxdt(1,mu,ilmn,ia,ispinor)
     316              :              end do
     317              :            end do
     318              :          end if
     319              :        end do
     320              :      end do
     321            0 :      if (choice==52) then
     322            0 :        enlj(2)=-enlj(2);enlj(4)=-enlj(4);enlj(6)=-enlj(6)
     323              :      end if
     324            0 :      enlout(1:6)=enlout(1:6)+enlj(1:6)
     325              :    end if
     326              : 
     327              : !  ======== Accumulate the contributions of twist derivatives of E wrt to k ==========
     328              : ! accumulate <u|dp_i/dk_(idir+1)>D_ij<dp_j/dk(idir+2)|u>
     329       473638 :    if (choice==53) then
     330            0 :      enlj(:)=zero
     331            0 :      ABI_MALLOC(cft,(3,nlmn))
     332            0 :      ABI_MALLOC(cfu,(3,nlmn))
     333              : !    If cplex=1, dgxdt is pure imaginary;
     334              : !    If cplex_fac=1, dgxdtfac is pure imaginary;
     335            0 :      do ispinor=1,nspinor
     336            0 :        do ia=1,nincat
     337            0 :         if(cplex==2)then
     338            0 :            cft(1:3,1:nlmn)=cmplx(dgxdt(1,1:3,1:nlmn,ia,ispinor),dgxdt(2,1:3,1:nlmn,ia,ispinor))
     339              :          else
     340            0 :            cft(1:3,1:nlmn)=cmplx(zero,dgxdt(1,1:3,1:nlmn,ia,ispinor))
     341              :          end if
     342            0 :          if(cplex_fac==2)then
     343            0 :            cfu(1:3,1:nlmn)=cmplx(dgxdtfac(1,1:3,1:nlmn,ia,ispinor),dgxdtfac(2,1:3,1:nlmn,ia,ispinor))
     344              :          else
     345            0 :            cfu(1:3,1:nlmn)=cmplx(zero,dgxdtfac(1,1:3,1:nlmn,ia,ispinor))
     346              :          end if
     347            0 :          do ilmn=1,nlmn
     348            0 :            do mu=1,3
     349            0 :              mut = twist_dir(2*mu-1)
     350            0 :              muu = twist_dir(2*mu)
     351            0 :              if (cplex == 2) then
     352            0 :                enlj(2*mu-1) = enlj(2*mu-1) + real(conjg(cft(mut,ilmn))*cfu(muu,ilmn))
     353            0 :                enlj(2*mu)   = enlj(2*mu)   + aimag(conjg(cft(mut,ilmn))*cfu(muu,ilmn))
     354              :              else
     355            0 :                enlj(mu) = enlj(mu) + real(conjg(cft(mut,ilmn))*cfu(muu,ilmn))
     356              :              end if
     357              :            end do ! end loop over mu=1,3
     358              :          end do ! end loop over ilmn states
     359              :        end do ! end loop over ia atoms
     360              :      end do ! end loop over ispinor
     361            0 :      do mu = 1, 3
     362            0 :        if (cplex == 2) then
     363            0 :          enlout(2*mu-1)=enlout(2*mu-1)+enlj(2*mu-1)
     364            0 :          enlout(2*mu)  =enlout(2*mu)  +enlj(2*mu)
     365              :        else
     366            0 :          enlout(mu)=enlout(mu)+enlj(mu)
     367              :        end if
     368              :      end do ! end loop over mu = 1, 3
     369            0 :      ABI_FREE(cft)
     370            0 :      ABI_FREE(cfu)
     371              :    end if
     372              : 
     373              : !  ====== Accumulate the effective charges contributions =========
     374       473638 :    if (choice==54) then
     375            0 :      ABI_MALLOC(enljj,(18))
     376            0 :      do ispinor=1,nspinor
     377            0 :        do ia=1,nincat
     378            0 :          enljj(1:18)=zero
     379            0 :          iashift=18*(ia+ia3-2)
     380              : !        If cplex=1, dgxdt is real for atm. pos, pure imaginary for k;
     381              : !        If cplex_fac=1, dgxdtfac is pure imaginary for k;
     382            0 :          if(cplex==2.and.cplex_fac==2) then
     383            0 :            do ilmn=1,nlmn
     384              :              mu=1;nu=1
     385            0 :              do mua=1,3 ! atm. pos
     386            0 :                do mub=1,3 ! k
     387              :                  enljj(nu)=enljj(nu) &
     388              : &                 +dgxdt(1,mua,ilmn,ia,ispinor)*dgxdtfac(1,3+mub,ilmn,ia,ispinor) &
     389              : &                 +dgxdt(2,mua,ilmn,ia,ispinor)*dgxdtfac(2,3+mub,ilmn,ia,ispinor) &
     390              : &                 +gxfac(1,ilmn,ia,ispinor)*d2gxdt(1,mu,ilmn,ia,ispinor) &
     391            0 : &                 +gxfac(2,ilmn,ia,ispinor)*d2gxdt(2,mu,ilmn,ia,ispinor)
     392              :                  enljj(nu+1)=enljj(nu+1) &
     393              : &                 +dgxdt(1,mua,ilmn,ia,ispinor)*dgxdtfac(2,3+mub,ilmn,ia,ispinor) &
     394              : &                 -dgxdt(2,mua,ilmn,ia,ispinor)*dgxdtfac(1,3+mub,ilmn,ia,ispinor) &
     395              : &                 +gxfac(1,ilmn,ia,ispinor)*d2gxdt(2,mu,ilmn,ia,ispinor) &
     396            0 : &                 -gxfac(2,ilmn,ia,ispinor)*d2gxdt(1,mu,ilmn,ia,ispinor)
     397            0 :                  mu=mu+1;nu=nu+2
     398              :                end do
     399              :              end do
     400              :            end do
     401            0 :          else if(cplex==1.and.cplex_fac==2)then
     402            0 :            do ilmn=1,nlmn
     403              :              mu=1;nu=1
     404            0 :              do mua=1,3 ! atm. pos
     405            0 :                do mub=1,3 ! k
     406              :                  enljj(nu)=enljj(nu) &
     407              : &                 +dgxdt(1,mua,ilmn,ia,ispinor)*dgxdtfac(1,3+mub,ilmn,ia,ispinor) &
     408            0 : &                 +gxfac(2,ilmn,ia,ispinor)*d2gxdt(1,mu,ilmn,ia,ispinor)
     409              :                  enljj(nu+1)=enljj(nu+1) &
     410              : &                 +dgxdt(1,mua,ilmn,ia,ispinor)*dgxdtfac(2,3+mub,ilmn,ia,ispinor) &
     411            0 : &                 +gxfac(1,ilmn,ia,ispinor)*d2gxdt(1,mu,ilmn,ia,ispinor)
     412            0 :                  mu=mu+1;nu=nu+2
     413              :                end do
     414              :              end do
     415              :            end do
     416            0 :          else if(cplex==1.and.cplex_fac==1)then
     417            0 :            do ilmn=1,nlmn
     418              :              mu=1;nu=1
     419            0 :              do mua=1,3 ! atm. pos
     420            0 :                do mub=1,3 ! k
     421              :                  enljj(nu+1)=enljj(nu+1) &
     422              : &                 +dgxdt(1,mua,ilmn,ia,ispinor)*dgxdtfac(1,3+mub,ilmn,ia,ispinor) &
     423            0 : &                 +gxfac(1,ilmn,ia,ispinor)*d2gxdt(1,mu,ilmn,ia,ispinor)
     424            0 :                  mu=mu+1;nu=nu+2
     425              :                end do
     426              :              end do
     427              :            end do
     428              :          end if
     429            0 :          enlout(iashift+1:iashift+18)=enlout(iashift+1:iashift+18)+enljj(1:18)
     430              :        end do
     431              :      end do
     432            0 :      ABI_FREE(enljj)
     433              :    end if
     434              : 
     435              : !  ====== Accumulate the piezoelectric tensor contributions =========
     436       473638 :    if (choice==55) then
     437            0 :      ABI_MALLOC(enljj,(36))
     438            0 :      do ispinor=1,nspinor
     439            0 :        do ia=1,nincat
     440            0 :          enljj(1:36)=zero;enlj(:)=zero
     441              : !        If cplex=1, dgxdt is real for strain, pure imaginary for k;
     442              : !        If cplex_fac=1, dgxdtfac is pure imaginary for k;
     443            0 :          if(cplex==2.and.cplex_fac==2) then
     444            0 :            do ilmn=1,nlmn
     445              : !            First compute 2nd-derivative contribution
     446              :              mu=1
     447            0 :              do mua=1,6 ! strain (lambda,nu)
     448            0 :                mua1=alpha(mua) ! (nu)
     449            0 :                mua2=beta(mua)  ! (lambda)
     450            0 :                do mub=1,3 ! k (mu)
     451            0 :                  muu=3*(gamma(mua1,mub)-1)+mua2
     452            0 :                  mut=3*(gamma(mua2,mub)-1)+mua1
     453              :                  d2gx(1:cplex)=half*(d2gxdt(1:cplex,muu,ilmn,ia,ispinor) &
     454            0 : &                 +d2gxdt(1:cplex,mut,ilmn,ia,ispinor))
     455              :                  enljj(mu)=enljj(mu) &
     456              : &                 +dgxdt(1,mua,ilmn,ia,ispinor)*dgxdtfac(1,6+mub,ilmn,ia,ispinor) &
     457              : &                 +dgxdt(2,mua,ilmn,ia,ispinor)*dgxdtfac(2,6+mub,ilmn,ia,ispinor) &
     458            0 : &                 +gxfac(1,ilmn,ia,ispinor)*d2gx(1)+gxfac(2,ilmn,ia,ispinor)*d2gx(2)
     459              :                  enljj(mu+1)=enljj(mu+1) &
     460              : &                 +dgxdt(1,mua,ilmn,ia,ispinor)*dgxdtfac(2,6+mub,ilmn,ia,ispinor) &
     461              : &                 -dgxdt(2,mua,ilmn,ia,ispinor)*dgxdtfac(1,6+mub,ilmn,ia,ispinor) &
     462            0 : &                 +gxfac(1,ilmn,ia,ispinor)*d2gx(2)-gxfac(2,ilmn,ia,ispinor)*d2gx(1)
     463            0 :                  mu=mu+2
     464              :                end do
     465              :              end do
     466              : !            Then store 1st-derivative contribution
     467              :              mu=1
     468            0 :              do nu=1,3
     469              :                enlj(mu  )=enlj(mu  )+gxfac(1,ilmn,ia,ispinor)*dgxdt(1,6+nu,ilmn,ia,ispinor) &
     470            0 : &               +gxfac(2,ilmn,ia,ispinor)*dgxdt(2,6+nu,ilmn,ia,ispinor)
     471              :                enlj(mu+1)=enlj(mu+1)+gxfac(1,ilmn,ia,ispinor)*dgxdt(2,6+nu,ilmn,ia,ispinor) &
     472            0 : &               -gxfac(2,ilmn,ia,ispinor)*dgxdt(1,6+nu,ilmn,ia,ispinor)
     473            0 :                mu=mu+2
     474              :              end do
     475              :            end do
     476            0 :          else if(cplex==1.and.cplex_fac==2)then
     477            0 :            do ilmn=1,nlmn
     478              : !            First compute 2nd-derivative contribution
     479              :              mu=1
     480            0 :              do mua=1,6 ! strain (lambda,nu)
     481            0 :                mua1=alpha(mua) ! (nu)
     482            0 :                mua2=beta(mua)  ! (lambda)
     483            0 :                do mub=1,3 ! k (mu)
     484            0 :                  muu=3*(gamma(mua1,mub)-1)+mua2
     485            0 :                  mut=3*(gamma(mua2,mub)-1)+mua1
     486            0 :                  d2gx(1)=half*(d2gxdt(1,muu,ilmn,ia,ispinor)+d2gxdt(1,mut,ilmn,ia,ispinor))
     487              :                  enljj(mu)=enljj(mu) &
     488              : &                 +dgxdt(1,mua,ilmn,ia,ispinor)*dgxdtfac(1,6+mub,ilmn,ia,ispinor) &
     489            0 : &                 +gxfac(2,ilmn,ia,ispinor)*d2gx(1)
     490              :                  enljj(mu+1)=enljj(mu+1) &
     491              : &                 +dgxdt(1,mua,ilmn,ia,ispinor)*dgxdtfac(2,6+mub,ilmn,ia,ispinor) &
     492            0 : &                 +gxfac(1,ilmn,ia,ispinor)*d2gx(1)
     493            0 :                  mu=mu+2
     494              :                end do
     495              :              end do
     496              : !            Then store 1st-derivative contribution
     497              :              mu=1
     498            0 :              do nu=1,3
     499            0 :                enlj(mu  )=enlj(mu  )+gxfac(2,ilmn,ia,ispinor)*dgxdt(1,6+nu,ilmn,ia,ispinor)
     500            0 :                enlj(mu+1)=enlj(mu+1)+gxfac(1,ilmn,ia,ispinor)*dgxdt(1,6+nu,ilmn,ia,ispinor)
     501            0 :                mu=mu+2
     502              :              end do
     503              :            end do
     504            0 :          else if(cplex==1.and.cplex_fac==1)then
     505            0 :            do ilmn=1,nlmn
     506              :              mu=1
     507            0 :              do mua=1,6 ! strain (lambda,nu)
     508            0 :                mua1=alpha(mua) ! (nu)
     509            0 :                mua2=beta(mua)  ! (lambda)
     510            0 :                do mub=1,3 ! k (mu)
     511            0 :                  muu=3*(gamma(mua1,mub)-1)+mua2
     512            0 :                  mut=3*(gamma(mua2,mub)-1)+mua1
     513            0 :                  d2gx(1)=half*(d2gxdt(1,muu,ilmn,ia,ispinor)+d2gxdt(1,mut,ilmn,ia,ispinor))
     514              :                  enljj(mu+1)=enljj(mu+1) &
     515              : &                 +dgxdt(1,mua,ilmn,ia,ispinor)*dgxdtfac(1,6+mub,ilmn,ia,ispinor) &
     516            0 : &                 +gxfac(1,ilmn,ia,ispinor)*d2gx(1)
     517            0 :                  mu=mu+2
     518              :                end do
     519              :              end do
     520              : !            Then store 1st-derivative contribution
     521              :              mu=1
     522            0 :              do nu=1,3
     523            0 :                enlj(mu+1)=enlj(mu+1)+gxfac(1,ilmn,ia,ispinor)*dgxdt(1,6+nu,ilmn,ia,ispinor)
     524            0 :                mu=mu+2
     525              :              end do
     526              :            end do
     527              :          end if
     528            0 :          enlout(1:36)=enlout(1:36)+enljj(1:36)
     529            0 :          ddkk(1:6)=ddkk(1:6)+enlj(1:6)
     530              :        end do
     531              :      end do
     532            0 :      ABI_FREE(enljj)
     533              :    end if
     534              : 
     535              : !  ======= Accumulate the elastic tensor contributions ==========
     536       473638 :    if (choice==6) then
     537         5760 :      do ispinor=1,nspinor
     538        11136 :        do ia=1,nincat
     539         5376 :          iashift=3*(ia+ia3-2)
     540        53312 :          do ilmn=1,nlmn
     541       135168 :            do iplex=1,cplex
     542       135168 :              enlk=enlk+gxfac(iplex,ilmn,ia,ispinor)*gx(iplex,ilmn,ia,ispinor)
     543              :            end do
     544       180224 :            enlj(1:3)=zero
     545       180224 :            do mu=1,3
     546       450560 :              do iplex=1,cplex
     547       405504 :                enlj(mu)=enlj(mu)+gxfac(iplex,ilmn,ia,ispinor)*dgxdt(iplex,6+mu,ilmn,ia,ispinor)
     548              :              end do
     549              :            end do
     550       180224 :            fnlk(iashift+1:iashift+3)=fnlk(iashift+1:iashift+3)+two*enlj(1:3)
     551       315392 :            enlj(1:6)=zero
     552       315392 :            do mu=1,6
     553       856064 :              do iplex=1,cplex
     554       811008 :                enlj(mu)=enlj(mu)+gxfac(iplex,ilmn,ia,ispinor)*dgxdt(iplex,mu,ilmn,ia,ispinor)
     555              :              end do
     556              :            end do
     557       315392 :            strnlk(1:6)=strnlk(1:6)+two*enlj(1:6)
     558       320768 :            do mub=1,6
     559       270336 :              mushift=6*(mub-1);nushift=(3*natom+6)*(mub-1)
     560      1892352 :              do mua=1,6
     561      1622016 :                mu=mushift+mua;nu=nushift+mua
     562      5136384 :                do iplex=1,cplex
     563              :                  enlout(nu)=enlout(nu)+two* &
     564              : &                 (gxfac(iplex,ilmn,ia,ispinor)*d2gxdt(iplex,mu,ilmn,ia,ispinor)&
     565      4866048 : &                 +dgxdtfac(iplex,mua,ilmn,ia,ispinor)*dgxdt(iplex,mub,ilmn,ia,ispinor))
     566              :                end do
     567              :              end do
     568       270336 :              mushift=36+3*(mub-1);nushift=6+iashift+(3*natom+6)*(mub-1)
     569      1126400 :              do mua=1,3
     570       811008 :                mu=mushift+mua;nu=nushift+mua
     571      2703360 :                do iplex=1,cplex
     572              :                  enlout(nu)=enlout(nu)+two* &
     573              : &                 (gxfac(iplex,ilmn,ia,ispinor)*d2gxdt(iplex,mu,ilmn,ia,ispinor)&
     574      2433024 : &                 +dgxdtfac(iplex,mub,ilmn,ia,ispinor)*dgxdt(iplex,6+mua,ilmn,ia,ispinor))
     575              :                end do
     576              :              end do
     577              :            end do
     578              :          end do
     579              :        end do
     580              :      end do
     581              :    end if
     582              : 
     583              : !  ======== Accumulate the contributions of 2nd-derivatives of E wrt to k ==========
     584       473638 :    if (choice==8) then
     585         2304 :      ABI_MALLOC(cft,(3,nlmn))
     586         1536 :      ABI_MALLOC(cfu,(3,nlmn))
     587         1536 :      do ispinor=1,nspinor
     588         2304 :        do ia=1,nincat
     589         5376 :          enlj(1:6)=zero
     590         6912 :          do ilmn=1,nlmn
     591        43776 :            do mu=1,6
     592       116736 :              do iplex=1,cplex
     593       110592 :                enlj(mu)=enlj(mu)+gxfac(iplex,ilmn,ia,ispinor)*d2gxdt(iplex,mu,ilmn,ia,ispinor)
     594              :              end do
     595              :            end do
     596              :          end do
     597              : !        If cplex=1, dgxdt is pure imaginary;
     598              : !        If cplex_fac=1, dgxdtfac is pure imaginary;
     599          768 :          if(cplex==2)then
     600        25344 :            cft(1:3,1:nlmn)=cmplx(dgxdt(1,1:3,1:nlmn,ia,ispinor),dgxdt(2,1:3,1:nlmn,ia,ispinor))
     601              :          else
     602            0 :            cft(1:3,1:nlmn)=cmplx(zero,dgxdt(1,1:3,1:nlmn,ia,ispinor))
     603              :          end if
     604          768 :          if(cplex_fac==2)then
     605        25344 :            cfu(1:3,1:nlmn)=cmplx(dgxdtfac(1,1:3,1:nlmn,ia,ispinor),dgxdtfac(2,1:3,1:nlmn,ia,ispinor))
     606              :          else
     607            0 :            cfu(1:3,1:nlmn)=cmplx(zero,dgxdtfac(1,1:3,1:nlmn,ia,ispinor))
     608              :          end if
     609         6912 :          do ilmn=1,nlmn
     610        43776 :            do mu=1,6
     611        36864 :              mua=alpha(mu);mub=beta(mu)
     612        43008 :              enlj(mu)=enlj(mu)+real(conjg(cfu(mub,ilmn))*cft(mua,ilmn))
     613              :            end do
     614              :          end do
     615         6144 :          enlout(1:6)=enlout(1:6)+two*enlj(1:6)
     616              :        end do
     617              :      end do
     618          768 :      ABI_FREE(cft)
     619          768 :      ABI_FREE(cfu)
     620              :    end if
     621              : 
     622              : !  ======== Accumulate the contributions of partial 2nd-derivatives of E wrt to k ==========
     623              : !  Full derivative wrt to k1, right derivative wrt to k2
     624       473638 :    if (choice==81) then
     625            0 :      ABI_MALLOC(cft,(3,nlmn))
     626            0 :      ABI_MALLOC(cfu,(6,nlmn))
     627            0 :      ABI_MALLOC(enljj,(18))
     628            0 :      do ispinor=1,nspinor
     629            0 :        do ia=1,nincat
     630            0 :          enljj(1:18)=zero
     631            0 :          if(cplex_fac==2)then !If cplex_fac=1, gxfac is pure real
     632            0 :            cft(1,1:nlmn)=cmplx(gxfac(1,1:nlmn,ia,ispinor),gxfac(2,1:nlmn,ia,ispinor))
     633              :          else
     634            0 :            cft(1,1:nlmn)=cmplx(gxfac(1,1:nlmn,ia,ispinor),zero)
     635              :          end if
     636            0 :          if(cplex==2)then !If cplex=1, d2gxdt is pure real
     637            0 :            cfu(1:6,1:nlmn)=cmplx(d2gxdt(1,1:6,1:nlmn,ia,ispinor),d2gxdt(2,1:6,1:nlmn,ia,ispinor))
     638              :          else
     639            0 :            cfu(1:6,1:nlmn)=cmplx(d2gxdt(1,1:6,1:nlmn,ia,ispinor),zero)
     640              :          end if
     641            0 :          do ilmn=1,nlmn
     642            0 :            do mu=1,3
     643            0 :              do nu=1,3
     644            0 :                muu=3*(mu-1)+nu ; mut=gamma(mu,nu)
     645            0 :                enljj(2*muu-1)=enljj(2*muu-1)+ real(conjg(cft(1,ilmn))*cfu(mut,ilmn))
     646            0 :                enljj(2*muu  )=enljj(2*muu  )+aimag(conjg(cft(1,ilmn))*cfu(mut,ilmn))
     647              :              end do
     648              :            end do
     649              :          end do
     650            0 :          if(cplex==2)then !If cplex=1, dgxdt is pure imaginary
     651            0 :            cft(1:3,1:nlmn)=cmplx(dgxdt(1,1:3,1:nlmn,ia,ispinor),dgxdt(2,1:3,1:nlmn,ia,ispinor))
     652              :          else
     653            0 :            cft(1:3,1:nlmn)=cmplx(zero,dgxdt(1,1:3,1:nlmn,ia,ispinor))
     654              :          end if
     655            0 :          if(cplex_fac==2)then !If cplex_fac=1, dgxdtfac is pure imaginary
     656            0 :            cfu(1:3,1:nlmn)=cmplx(dgxdtfac(1,1:3,1:nlmn,ia,ispinor),dgxdtfac(2,1:3,1:nlmn,ia,ispinor))
     657              :          else
     658            0 :            cfu(1:3,1:nlmn)=cmplx(zero,dgxdtfac(1,1:3,1:nlmn,ia,ispinor))
     659              :          end if
     660            0 :          do ilmn=1,nlmn
     661            0 :            do mu=1,3
     662            0 :              do nu=1,3
     663            0 :                muu=3*(mu-1)+nu
     664            0 :                enljj(2*muu-1)=enljj(2*muu-1)+ real(conjg(cft(mu,ilmn))*cfu(nu,ilmn))
     665            0 :                enljj(2*muu  )=enljj(2*muu  )+aimag(conjg(cft(mu,ilmn))*cfu(nu,ilmn))
     666              :              end do
     667              :            end do
     668              :          end do
     669            0 :          enlout(1:18)=enlout(1:18)+enljj(1:18)
     670              :        end do
     671              :      end do
     672            0 :      ABI_FREE(cft)
     673            0 :      ABI_FREE(cfu)
     674            0 :      ABI_FREE(enljj)
     675              :    end if
     676              : 
     677              :  end if
     678              : 
     679       738502 :  if (paw_opt==3) then
     680              : 
     681              : !  ============== Accumulate contribution to <c|S|c> ===============
     682       264864 :    if (choice==1) then
     683       220960 :      if (present(enlout_im).and.cplex==2) then ! cplex=2
     684      2217120 :        do idat_left=1,ndat_left
     685      4213280 :          do ispinor=1,nspinor
     686      8549120 :            do ia=1,nincat
     687     54296960 :              do ilmn=1,nlmn
     688     47744000 :                enlout   (idat_left)=enlout   (idat_left)+gxfac_sij(1,ilmn,ia,ispinor)*gx(1,ilmn,ia,ispinor+(idat_left-1)*nspinor)
     689     47744000 :                enlout   (idat_left)=enlout   (idat_left)+gxfac_sij(2,ilmn,ia,ispinor)*gx(2,ilmn,ia,ispinor+(idat_left-1)*nspinor)
     690     47744000 :                enlout_im(idat_left)=enlout_im(idat_left)+gxfac_sij(2,ilmn,ia,ispinor)*gx(1,ilmn,ia,ispinor+(idat_left-1)*nspinor)
     691     52300800 :                enlout_im(idat_left)=enlout_im(idat_left)-gxfac_sij(1,ilmn,ia,ispinor)*gx(2,ilmn,ia,ispinor+(idat_left-1)*nspinor)
     692              :              end do
     693              :            end do
     694              :          end do
     695              :        end do
     696              :      else ! only the real part is needed or the imaginary part is zero
     697            0 :        do idat_left=1,ndat_left
     698            0 :          do ispinor=1,nspinor
     699            0 :            do ia=1,nincat
     700            0 :              do ilmn=1,nlmn
     701            0 :                do iplex=1,cplex
     702              :                  enlout(idat_left)=enlout(idat_left)+&
     703            0 : &                   gxfac_sij(iplex,ilmn,ia,ispinor)*gx(iplex,ilmn,ia,ispinor+(idat_left-1)*nspinor)
     704              :                end do
     705              :              end do
     706              :            end do
     707              :          end do
     708              :        end do
     709              :      end if
     710              :    end if
     711              : 
     712              : !  ============== Accumulate contribution to <c|dS/d_atm_pos|c> ===============
     713       264864 :    if (choice==2.or.choice==23) then
     714        13824 :      ishift=0;if (choice==23) ishift=6
     715        27648 :      do ispinor=1,nspinor
     716        41472 :        do ia=1,nincat
     717        55296 :          enlj(1:3)=zero
     718        13824 :          iashift=3*(ia+ia3-2)
     719       124416 :          do ilmn=1,nlmn
     720       456192 :            do mu=1,3
     721      1105920 :              do iplex=1,cplex
     722       995328 :                enlj(mu)=enlj(mu)+gxfac_sij(iplex,ilmn,ia,ispinor)*dgxdt(iplex,mu+ishift,ilmn,ia,ispinor)
     723              :              end do
     724              :            end do
     725              :          end do
     726        69120 :          enlout(iashift+1:iashift+3)=enlout(iashift+1:iashift+3)+two*enlj(1:3)
     727              :        end do
     728              :      end do
     729              :    end if
     730              : 
     731              : !  ============== Accumulate contribution to <c|dS/d_strain|c> ===============
     732       264864 :    if (choice==3.or.choice==23) then
     733            0 :      enlj(1:6)=zero
     734            0 :      do ispinor=1,nspinor
     735            0 :        do ia=1,nincat
     736            0 :          do ilmn=1,nlmn
     737            0 :            gxfacj(1:cplex)=gxfac_sij(1:cplex,ilmn,ia,ispinor)
     738            0 :            do iplex=1,cplex
     739            0 :              enlk=enlk+gxfacj(iplex)*gx(iplex,ilmn,ia,ispinor)
     740              :            end do
     741            0 :            do mu=1,6
     742            0 :              do iplex=1,cplex
     743            0 :                enlj(mu)=enlj(mu)+gxfacj(iplex)*dgxdt(iplex,mu,ilmn,ia,ispinor)
     744              :              end do
     745              :            end do
     746              :          end do
     747              :        end do
     748              :      end do
     749            0 :      enlout(1:6)=enlout(1:6)+two*enlj(1:6)
     750              :    end if
     751              : 
     752              : !  ======== Accumulate the contributions of derivatives of <c|S|c> wrt to k ==========
     753       264864 :    if (choice==5) then
     754         4608 :      enlj(1:3)=zero
     755              : !    If cplex=1, gxfac is real and dgxdt is pure imaginary; thus there is no contribution
     756         1152 :      if(cplex==2)then
     757         2304 :        do ispinor=1,nspinor
     758         3456 :          do ia=1,nincat
     759        11520 :            do ilmn=1,nlmn
     760        38016 :              do mu=1,3
     761        92160 :                do iplex=1,cplex
     762        82944 :                  enlj(mu)=enlj(mu)+gxfac_sij(iplex,ilmn,ia,ispinor)*dgxdt(iplex,mu,ilmn,ia,ispinor)
     763              :                end do
     764              :              end do
     765              :            end do
     766              :          end do
     767              :        end do
     768              :      end if
     769         4608 :      enlout(1:3)=enlout(1:3)+two*enlj(1:3)
     770              :    end if
     771              : 
     772              : !  ====== Accumulate the contributions of left or right derivatives of <c|S|c> wrt to k ==========
     773              : !  Choice 51: right derivative wrt to k ; Choice 52: left derivative wrt to k
     774       264864 :    if (choice==51.or.choice==52) then
     775            0 :      enlj(1:6)=zero
     776            0 :      do ispinor=1,nspinor
     777            0 :        do ia=1,nincat
     778            0 :          if(cplex==2)then
     779            0 :            do ilmn=1,nlmn
     780            0 :              do mu=1,3
     781              :                enlj(2*mu-1)=enlj(2*mu-1)+gxfac_sij(1,ilmn,ia,ispinor)*dgxdt(1,mu,ilmn,ia,ispinor) &
     782            0 : &               +gxfac_sij(2,ilmn,ia,ispinor)*dgxdt(2,mu,ilmn,ia,ispinor)
     783              :                enlj(2*mu  )=enlj(2*mu  )+gxfac_sij(1,ilmn,ia,ispinor)*dgxdt(2,mu,ilmn,ia,ispinor) &
     784            0 : &               -gxfac_sij(2,ilmn,ia,ispinor)*dgxdt(1,mu,ilmn,ia,ispinor)
     785              :              end do
     786              :            end do
     787            0 :          else if (cplex_fac==2) then
     788            0 :            do ilmn=1,nlmn
     789            0 :              do mu=1,3
     790            0 :                enlj(2*mu-1)=enlj(2*mu-1)+gxfac_sij(2,ilmn,ia,ispinor)*dgxdt(1,mu,ilmn,ia,ispinor)
     791            0 :                enlj(2*mu  )=enlj(2*mu  )+gxfac_sij(1,ilmn,ia,ispinor)*dgxdt(1,mu,ilmn,ia,ispinor)
     792              :              end do
     793              :            end do
     794            0 :          else if (cplex_fac==1) then
     795            0 :            do ilmn=1,nlmn
     796            0 :              do mu=1,3
     797            0 :                enlj(2*mu  )=enlj(2*mu  )+gxfac_sij(1,ilmn,ia,ispinor)*dgxdt(1,mu,ilmn,ia,ispinor)
     798              :              end do
     799              :            end do
     800              :          end if
     801              :        end do
     802              :      end do
     803            0 :      if (choice==52) then
     804            0 :        enlj(2)=-enlj(2);enlj(4)=-enlj(4);enlj(6)=-enlj(6)
     805              :      end if
     806            0 :      enlout(1:6)=enlout(1:6)+enlj(1:6)
     807              :    end if
     808              : 
     809              : !  ====== Accumulate the contributions of twist derivatives of <c|S|c> wrt to k ==========
     810              : ! Choice 53: <u|dp_i/dk_(idir+1)>Sij<dp_j/dk_(idir+2)|u>
     811       264864 :    if (choice==53) then
     812            0 :      enlj(:)=zero
     813            0 :      ABI_MALLOC(cft,(3,nlmn))
     814            0 :      ABI_MALLOC(cfu,(3,nlmn))
     815              : !    If cplex=1, dgxdt is pure imaginary;
     816              : !    If cplex_fac=1, dgxdtfac is pure imaginary;
     817            0 :      do ispinor=1,nspinor
     818            0 :        do ia=1,nincat
     819            0 :         if(cplex==2)then
     820            0 :            cft(1:3,1:nlmn)=cmplx(dgxdt(1,1:3,1:nlmn,ia,ispinor),dgxdt(2,1:3,1:nlmn,ia,ispinor))
     821              :          else
     822            0 :            cft(1:3,1:nlmn)=cmplx(zero,dgxdt(1,1:3,1:nlmn,ia,ispinor))
     823              :          end if
     824            0 :          if(cplex_fac==2)then
     825            0 :            cfu(1:3,1:nlmn)=cmplx(dgxdtfac_sij(1,1:3,1:nlmn,ia,ispinor),dgxdtfac_sij(2,1:3,1:nlmn,ia,ispinor))
     826              :          else
     827            0 :            cfu(1:3,1:nlmn)=cmplx(zero,dgxdtfac_sij(1,1:3,1:nlmn,ia,ispinor))
     828              :          end if
     829            0 :          do ilmn=1,nlmn
     830            0 :            do mu=1,3
     831            0 :              mut = twist_dir(2*mu-1)
     832            0 :              muu = twist_dir(2*mu)
     833            0 :              if (cplex == 2) then
     834            0 :                enlj(2*mu-1) = enlj(2*mu-1) + real(conjg(cft(mut,ilmn))*cfu(muu,ilmn))
     835            0 :                enlj(2*mu)   = enlj(2*mu)   + aimag(conjg(cft(mut,ilmn))*cfu(muu,ilmn))
     836              :              else
     837            0 :                enlj(mu) = enlj(mu) + real(conjg(cft(mut,ilmn))*cfu(muu,ilmn))
     838              :              end if
     839              :            end do ! end loop over mu=1,3
     840              :          end do ! end loop over ilmn states
     841              :        end do ! end loop over ia atoms
     842              :      end do ! end loop over ispinor
     843            0 :      do mu = 1, 3
     844            0 :        if (cplex == 2) then
     845            0 :          enlout(2*mu-1)=enlout(2*mu-1)+enlj(2*mu-1)
     846            0 :          enlout(2*mu)  =enlout(2*mu)  +enlj(2*mu)
     847              :        else
     848            0 :          enlout(mu)=enlout(mu)+enlj(mu)
     849              :        end if
     850              :      end do ! end loop over mu = 1, 3
     851            0 :      ABI_FREE(cft)
     852            0 :      ABI_FREE(cfu)
     853              :    end if
     854              : 
     855              : !  ====== Accumulate contribution to <c|d2S/d_atm_pos d_left_k|c> =========
     856       264864 :    if (choice==54) then
     857        22624 :      ABI_MALLOC(enljj,(18))
     858        45248 :      do ispinor=1,nspinor
     859        68672 :        do ia=1,nincat
     860       445056 :          enljj(1:18)=zero
     861        23424 :          iashift=18*(ia+ia3-2)
     862        23424 :          if(cplex==2) then
     863       220736 :            do ilmn=1,nlmn
     864              :              mu=1;nu=1
     865       812672 :              do mua=1,3 ! atm. pos
     866      2565056 :                do mub=1,3 ! k
     867              :                  enljj(nu)=enljj(nu) &
     868              : &                 +dgxdt(1,mua,ilmn,ia,ispinor)*dgxdtfac_sij(1,3+mub,ilmn,ia,ispinor) &
     869              : &                 +dgxdt(2,mua,ilmn,ia,ispinor)*dgxdtfac_sij(2,3+mub,ilmn,ia,ispinor) &
     870              : &                 +gxfac_sij(1,ilmn,ia,ispinor)*d2gxdt(1,mu,ilmn,ia,ispinor) &
     871      1775808 : &                 +gxfac_sij(2,ilmn,ia,ispinor)*d2gxdt(2,mu,ilmn,ia,ispinor)
     872              : 
     873              :                  enljj(nu+1)=enljj(nu+1) &
     874              : &                 +dgxdt(1,mua,ilmn,ia,ispinor)*dgxdtfac_sij(2,3+mub,ilmn,ia,ispinor) &
     875              : &                 -dgxdt(2,mua,ilmn,ia,ispinor)*dgxdtfac_sij(1,3+mub,ilmn,ia,ispinor) &
     876              : &                 +gxfac_sij(1,ilmn,ia,ispinor)*d2gxdt(2,mu,ilmn,ia,ispinor) &
     877      1775808 : &                 -gxfac_sij(2,ilmn,ia,ispinor)*d2gxdt(1,mu,ilmn,ia,ispinor)
     878              : 
     879      2367744 :                  mu=mu+1;nu=nu+2
     880              :                end do
     881              :              end do
     882              :            end do
     883              : !        If cplex=1, dgxdt, d2gxdt and dgxdtfac_sij are real for atm. pos, pure imaginary for k
     884              :          else
     885            0 :            do ilmn=1,nlmn
     886              :              mu=1;nu=1
     887            0 :              do mua=1,3 ! atm. pos
     888            0 :                do mub=1,3 ! k
     889              :                  enljj(nu+1)=enljj(nu+1) &
     890              : &                 +dgxdt(1,mua,ilmn,ia,ispinor)*dgxdtfac_sij(1,3+mub,ilmn,ia,ispinor) &
     891            0 : &                 +gxfac_sij(1,ilmn,ia,ispinor)*d2gxdt(1,mu,ilmn,ia,ispinor)
     892            0 :                  mu=mu+1;nu=nu+2
     893              :                end do
     894              :              end do
     895              :            end do
     896              :          end if
     897       467680 :          enlout(iashift+1:iashift+18)=enlout(iashift+1:iashift+18)+enljj(1:18)
     898              :        end do
     899              :      end do
     900        22624 :      ABI_FREE(enljj)
     901              :    end if
     902              : 
     903              : !  ====== Accumulate contribution to <c|d2S/d_dstrain d_right_k|c> =========
     904       264864 :    if (choice==55) then
     905         5152 :      ABI_MALLOC(enljj,(36))
     906        10304 :      do ispinor=1,nspinor
     907        16096 :        do ia=1,nincat
     908       289600 :          enljj(1:36)=zero;enlj(:)=zero
     909              : !        If cplex=1, dgxdt is real for strain, pure imaginary for k;
     910              : !        If cplex_fac=1, dgxdtfac is pure imaginary for k;
     911         5792 :          if(cplex==2.and.cplex_fac==2) then
     912        56288 :            do ilmn=1,nlmn
     913              : !            First compute 2nd-derivative contribution
     914              :              mu=1
     915       353472 :              do mua=1,6 ! strain (lambda,nu)
     916       302976 :                mua1=alpha(mua) ! (nu)
     917       302976 :                mua2=beta(mua)  ! (lambda)
     918      1262400 :                do mub=1,3 ! k (mu)
     919       908928 :                  muu=3*(gamma(mua1,mub)-1)+mua2
     920       908928 :                  mut=3*(gamma(mua2,mub)-1)+mua1
     921              :                  d2gx(1:cplex)=half*(d2gxdt(1:cplex,muu,ilmn,ia,ispinor) &
     922      2726784 : &                 +d2gxdt(1:cplex,mut,ilmn,ia,ispinor))
     923              :                  enljj(mu)=enljj(mu) &
     924              : &                 +dgxdt(1,mua,ilmn,ia,ispinor)*dgxdtfac_sij(1,6+mub,ilmn,ia,ispinor) &
     925              : &                 +dgxdt(2,mua,ilmn,ia,ispinor)*dgxdtfac_sij(2,6+mub,ilmn,ia,ispinor) &
     926       908928 : &                 +gxfac_sij(1,ilmn,ia,ispinor)*d2gx(1)+gxfac_sij(2,ilmn,ia,ispinor)*d2gx(2)
     927              :                  enljj(mu+1)=enljj(mu+1) &
     928              : &                 +dgxdt(1,mua,ilmn,ia,ispinor)*dgxdtfac_sij(2,6+mub,ilmn,ia,ispinor) &
     929              : &                 -dgxdt(2,mua,ilmn,ia,ispinor)*dgxdtfac_sij(1,6+mub,ilmn,ia,ispinor) &
     930       908928 : &                 +gxfac_sij(1,ilmn,ia,ispinor)*d2gx(2)-gxfac_sij(2,ilmn,ia,ispinor)*d2gx(1)
     931      1211904 :                  mu=mu+2
     932              :                end do
     933              :              end do
     934              : !            Then store 1st-derivative contribution
     935              :              mu=1
     936       207776 :              do nu=1,3
     937              :                enlj(mu  )=enlj(mu  )+gxfac_sij(1,ilmn,ia,ispinor)*dgxdt(1,6+nu,ilmn,ia,ispinor) &
     938       151488 : &               +gxfac_sij(2,ilmn,ia,ispinor)*dgxdt(2,6+nu,ilmn,ia,ispinor)
     939              :                enlj(mu+1)=enlj(mu+1)+gxfac_sij(1,ilmn,ia,ispinor)*dgxdt(2,6+nu,ilmn,ia,ispinor) &
     940       151488 : &               -gxfac_sij(2,ilmn,ia,ispinor)*dgxdt(1,6+nu,ilmn,ia,ispinor)
     941       201984 :                mu=mu+2
     942              :              end do
     943              :            end do
     944              : !        If cplex=1, dgxdt, d2gxdt and dgxdtfac_sij are real for atm. pos, pure imaginary for k
     945              :          else
     946            0 :            do ilmn=1,nlmn
     947              :              mu=1
     948            0 :              do mua=1,6 ! strain (lambda,nu)
     949            0 :                mua1=alpha(mua) ! (nu)
     950            0 :                mua2=beta(mua)  ! (lambda)
     951            0 :                do mub=1,3 ! k (mu)
     952            0 :                  muu=3*(gamma(mua1,mub)-1)+mua2
     953            0 :                  mut=3*(gamma(mua2,mub)-1)+mua1
     954            0 :                  d2gx(1)=half*(d2gxdt(1,muu,ilmn,ia,ispinor)+d2gxdt(1,mut,ilmn,ia,ispinor))
     955              :                  enljj(mu+1)=enljj(mu+1) &
     956              : &                 +dgxdt(1,mua,ilmn,ia,ispinor)*dgxdtfac_sij(1,6+mub,ilmn,ia,ispinor) &
     957            0 : &                 +gxfac_sij(1,ilmn,ia,ispinor)*d2gx(1)
     958            0 :                  mu=mu+2
     959              :                end do
     960              :              end do
     961              : !            Then store 1st-derivative contribution
     962              :              mu=1
     963            0 :              do nu=1,3
     964            0 :                enlj(mu+1)=enlj(mu+1)+gxfac_sij(1,ilmn,ia,ispinor)*dgxdt(1,6+nu,ilmn,ia,ispinor)
     965            0 :                mu=mu+2
     966              :              end do
     967              :            end do
     968              :          end if
     969       214304 :          enlout(1:36)=enlout(1:36)+enljj(1:36)
     970        45696 :          ddkk(1:6)=ddkk(1:6)+enlj(1:6)
     971              :        end do
     972              :      end do
     973         5152 :      ABI_FREE(enljj)
     974              :    end if
     975              : 
     976              : !  ======  Accumulate contribution to <c|d2S/d_k d_k|c> =========
     977       264864 :    if (choice==8) then
     978            0 :      ABI_MALLOC(cft,(3,nlmn))
     979            0 :      ABI_MALLOC(cfu,(3,nlmn))
     980            0 :      do ispinor=1,nspinor
     981            0 :        do ia=1,nincat
     982            0 :          enlj(1:6)=zero
     983            0 :          do ilmn=1,nlmn
     984            0 :            do mu=1,6
     985            0 :              do iplex=1,cplex
     986            0 :                enlj(mu)=enlj(mu)+gxfac_sij(iplex,ilmn,ia,ispinor)*d2gxdt(iplex,mu,ilmn,ia,ispinor)
     987              :              end do
     988              :            end do
     989              :          end do
     990              : !        If cplex=1, dgxdt is pure imaginary, dgxdtfac_sij is pure imaginary;
     991            0 :          if(cplex==2)then
     992            0 :            cft(1:3,1:nlmn)=cmplx(dgxdt(1,1:3,1:nlmn,ia,ispinor),dgxdt(2,1:3,1:nlmn,ia,ispinor))
     993            0 :            cfu(1:3,1:nlmn)=cmplx(dgxdtfac_sij(1,1:3,1:nlmn,ia,ispinor),dgxdtfac_sij(2,1:3,1:nlmn,ia,ispinor))
     994              :          else
     995            0 :            cft(1:3,1:nlmn)=cmplx(zero,dgxdt(1,1:3,1:nlmn,ia,ispinor))
     996            0 :            cfu(1:3,1:nlmn)=cmplx(zero,dgxdtfac_sij(1,1:3,1:nlmn,ia,ispinor))
     997              :          end if
     998            0 :          do ilmn=1,nlmn
     999            0 :            do mu=1,6
    1000            0 :              mua=alpha(mu);mub=beta(mu)
    1001            0 :              enlj(mu)=enlj(mu)+real(conjg(cfu(mub,ilmn))*cft(mua,ilmn))
    1002              :            end do
    1003              :          end do
    1004            0 :          enlout(1:6)=enlout(1:6)+two*enlj(1:6)
    1005              :        end do
    1006              :      end do
    1007            0 :      ABI_FREE(cft)
    1008            0 :      ABI_FREE(cfu)
    1009              :    end if
    1010              : 
    1011              : !  ======  Accumulate contribution to <c|d/d_k[d(right)S/d_k]|c> =========
    1012              : !  Full derivative wrt to k1, right derivative wrt to k2
    1013       264864 :    if (choice==81) then
    1014         3456 :      ABI_MALLOC(cft,(3,nlmn))
    1015         3456 :      ABI_MALLOC(cfu,(6,nlmn))
    1016         1152 :      ABI_MALLOC(enljj,(18))
    1017         2304 :      do ispinor=1,nspinor
    1018         3456 :        do ia=1,nincat
    1019        21888 :          enljj(1:18)=zero
    1020         1152 :          if(cplex_fac==2)then !If cplex_fac=1, gxfac is pure real
    1021        10368 :            cft(1,1:nlmn)=cmplx(gxfac_sij(1,1:nlmn,ia,ispinor),gxfac_sij(2,1:nlmn,ia,ispinor))
    1022              :          else
    1023            0 :            cft(1,1:nlmn)=cmplx(gxfac_sij(1,1:nlmn,ia,ispinor),zero)
    1024              :          end if
    1025         1152 :          if(cplex==2)then !If cplex=1, d2gxdt is pure real
    1026        65664 :            cfu(1:6,1:nlmn)=cmplx(d2gxdt(1,1:6,1:nlmn,ia,ispinor),d2gxdt(2,1:6,1:nlmn,ia,ispinor))
    1027              :          else
    1028            0 :            cfu(1:6,1:nlmn)=cmplx(d2gxdt(1,1:6,1:nlmn,ia,ispinor),zero)
    1029              :          end if
    1030        10368 :          do ilmn=1,nlmn
    1031        38016 :            do mu=1,3
    1032       119808 :              do nu=1,3
    1033        82944 :                muu=3*(mu-1)+nu ; mut=gamma(mu,nu)
    1034        82944 :                enljj(2*muu-1)=enljj(2*muu-1)+ real(conjg(cft(1,ilmn))*cfu(mut,ilmn))
    1035       110592 :                enljj(2*muu  )=enljj(2*muu  )+aimag(conjg(cft(1,ilmn))*cfu(mut,ilmn))
    1036              :              end do
    1037              :            end do
    1038              :          end do
    1039         1152 :          if(cplex==2)then !If cplex=1, dgxdt is pure imaginary
    1040        38016 :            cft(1:3,1:nlmn)=cmplx(dgxdt(1,1:3,1:nlmn,ia,ispinor),dgxdt(2,1:3,1:nlmn,ia,ispinor))
    1041              :          else
    1042            0 :            cft(1:3,1:nlmn)=cmplx(zero,dgxdt(1,1:3,1:nlmn,ia,ispinor))
    1043              :          end if
    1044         1152 :          if(cplex_fac==2)then !If cplex_fac=1, dgxdtfac is pure imaginary
    1045        38016 :            cfu(1:3,1:nlmn)=cmplx(dgxdtfac_sij(1,1:3,1:nlmn,ia,ispinor),dgxdtfac_sij(2,1:3,1:nlmn,ia,ispinor))
    1046              :          else
    1047            0 :            cfu(1:3,1:nlmn)=cmplx(zero,dgxdtfac_sij(1,1:3,1:nlmn,ia,ispinor))
    1048              :          end if
    1049        10368 :          do ilmn=1,nlmn
    1050        38016 :            do mu=1,3
    1051       119808 :              do nu=1,3
    1052        82944 :                muu=3*(mu-1)+nu
    1053        82944 :                enljj(2*muu-1)=enljj(2*muu-1)+ real(conjg(cft(mu,ilmn))*cfu(nu,ilmn))
    1054       110592 :                enljj(2*muu  )=enljj(2*muu  )+aimag(conjg(cft(mu,ilmn))*cfu(nu,ilmn))
    1055              :              end do
    1056              :            end do
    1057              :          end do
    1058        23040 :          enlout(1:18)=enlout(1:18)+enljj(1:18)
    1059              :        end do
    1060              :      end do
    1061         1152 :      ABI_FREE(cft)
    1062         1152 :      ABI_FREE(cfu)
    1063         1152 :      ABI_FREE(enljj)
    1064              :    end if
    1065              : 
    1066              :  end if
    1067              : 
    1068       738502 : end subroutine opernld_ylm
    1069              : !!***
    1070              : 
    1071              : end module m_opernld_ylm
    1072              : !!***
        

Generated by: LCOV version 2.3-1