LCOV - code coverage report
Current view: top level - src/66_nonlocal - m_nonlop_pl.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 90.0 % 568 511
Test Date: 2026-09-19 17:42:43 Functions: 100.0 % 5 5

            Line data    Source code
       1              : !!****m* ABINIT/m_nonlop_pl
       2              : !! NAME
       3              : !!  nonlop_pl
       4              : !!
       5              : !! FUNCTION
       6              : !!
       7              : !! COPYRIGHT
       8              : !!  Copyright (C) 1998-2026 ABINIT group (DCA, XG, GMR, GZ, MT, FF, DRH)
       9              : !!  This file is distributed under the terms of the
      10              : !!  GNU General Public License, see ~abinit/COPYING
      11              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      12              : !!
      13              : !! PARENTS
      14              : !!      m_nonlop
      15              : !!
      16              : !! CHILDREN
      17              : !!
      18              : !! SOURCE
      19              : 
      20              : #if defined HAVE_CONFIG_H
      21              : #include "config.h"
      22              : #endif
      23              : 
      24              : #include "abi_common.h"
      25              : 
      26              : module m_nonlop_pl
      27              : 
      28              :  use defs_basis
      29              :  use m_errors
      30              :  use m_abicore
      31              :  use m_xmpi
      32              :  use m_contistr01
      33              :  use m_contistr03
      34              :  use m_contistr12
      35              :  use m_contstr21
      36              :  use m_contstr23
      37              :  use m_contstr25
      38              :  use m_contstr25a
      39              :  use m_contstr26
      40              :  use m_metstr
      41              :  use m_opernl
      42              : 
      43              :  use defs_abitypes,   only : MPI_type
      44              :  use m_geometry,      only : strconv
      45              :  use m_kg,            only : ph1d3d
      46              :  use m_contract,      only : cont22cso, cont22so, cont24, cont33cso, cont33so, cont35, cont22, cont3, cont13, &
      47              :                              metcon, metcon_so, metric_so
      48              :  use m_numeric_tools, only : geteuler
      49              :  implicit none
      50              : 
      51              :  private
      52              : !!***
      53              : 
      54              :  public :: nonlop_pl
      55              : !!***
      56              : 
      57              : contains
      58              : !!***
      59              : 
      60              : !!****f* ABINIT/nonlop_pl
      61              : !! NAME
      62              : !! nonlop_pl
      63              : !!
      64              : !! FUNCTION
      65              : !! * Compute application of a nonlocal operator Vnl in order to get:
      66              : !!    - contracted elements (energy, forces, stresses, ...), if signs=1
      67              : !!    - a function in reciprocal space (|out> = Vnl|in>), if signs=2
      68              : !!   Operator Vnl, as the following form:
      69              : !!    $Vnl=sum_{R,lmn,l''m''n''} {|P_{Rlmn}> Enl^{R}_{lmn,l''m''n''} <P_{Rl''m''n''}|}$
      70              : !!   Operator Vnl is -- in the typical case -- the nonlocal potential.
      71              : !!   - With norm-conserving pseudopots, $Enl^{R}_{lmn,l''m''n''}$ is the
      72              : !!     Kleinmann-Bylander energy $Ekb^{R}_{ln}$.
      73              : !!   - The |P_{Rlmn}> are the projector functions.
      74              : !! * This routine uses Legendre polynomials Pl to express Vnl.
      75              : !!
      76              : !! INPUTS
      77              : !!  choice: chooses possible output:
      78              : !!    choice=1 => a non-local energy contribution
      79              : !!          =2 => a gradient with respect to atomic position(s)
      80              : !!          =3 => a gradient with respect to strain(s)
      81              : !!          =23=> a gradient with respect to atm. pos. and strain(s)
      82              : !!          =4 => a gradient and 2nd derivative with respect to atomic pos.
      83              : !!          =5 => a gradient with respect to k wavevector
      84              : !!          =6 => 2nd derivatives with respect to strain
      85              : !!  dimekb1,dimekb2=dimensions of ekb (see ekb)
      86              : !!  dimffnlin=second dimension of ffnlin (1+number of derivatives)
      87              : !!  dimffnlout=second dimension of ffnlout (1+number of derivatives)
      88              : !!  ekb(dimekb1,dimekb2,nspinortot**2)= (Real) Kleinman-Bylander energies (hartree)
      89              : !!                                   dimekb1=lmnmax  -  dimekp2=ntypat
      90              : !!  ffnlin(npwin,dimffnlin,lmnmax,ntypat)=nonlocal form factors to be used
      91              : !!          for the application of the nonlocal operator to the |in> vector
      92              : !!  ffnlout(npwout,dimffnlout,lmnmax,ntypat)=nonlocal form factors to be used
      93              : !!          for the application of the nonlocal operator to the |out> vector
      94              : !!  gmet(3,3)=metric tensor for G vecs (in bohr**-2)
      95              : !!  gprimd(3,3)=dimensional reciprocal space primitive translations
      96              : !!   (bohr^-1)
      97              : !!  idir=direction of the - atom to be moved in the case (choice=2,signs=2),
      98              : !!                        - k point direction in the case (choice=5,signs=2)
      99              : !!                        - strain component (1:6) in the case (choice=3,signs=2) or (choice=6,signs=1)
     100              : !!  indlmn(6,i,ntypat)= array giving l,m,n,lm,ln,s for i=ln
     101              : !!  istwf_k=option parameter that describes the storage of wfs
     102              : !!  kgin(3,npwin)=integer coords of planewaves in basis sphere, for the |in> vector
     103              : !!  kgout(3,npwout)=integer coords of planewaves in basis sphere, for the |out> vector
     104              : !!  kpgin(npw,npkgin)= (k+G) components and related data, for the |in> vector
     105              : !!  kpgout(npw,nkpgout)=(k+G) components and related data, for the |out> vector
     106              : !!  kptin(3)=k point in terms of recip. translations, for the |in> vector
     107              : !!  kptout(3)=k point in terms of recip. translations, for the |out> vector
     108              : !!  lmnmax=max. number of (l,m,n) components over all types of atoms
     109              : !!  matblk=dimension of the arrays ph3din and ph3dout
     110              : !!  mgfft=maximum size of 1D FFTs
     111              : !!  mpi_enreg=information about MPI parallelization
     112              : !!  natom=number of atoms in cell
     113              : !!  nattyp(ntypat)=number of atoms of each type
     114              : !!  ngfft(18)=contain all needed information about 3D FFT, see ~abinit/doc/variables/vargs.htm#ngfft
     115              : !!  nkpgin,nkpgout=second sizes of arrays kpgin/kpgout
     116              : !!  nloalg(3)=governs the choice of the algorithm for nonlocal operator
     117              : !!  nnlout=dimension of enlout: choice=1=>nnlout=1   choice=2=>nnlout=3*natom
     118              : !!                              choice=3=>nnlout=6   choice=4=>nnlout=6*natom
     119              : !!                              choice=5=>nnlout=1   choice=6=>nnlout=6*(3*natom+6)
     120              : !!                              choice=23=>nnlout=6+3*natom
     121              : !!  npwin=number of planewaves for given k point, for the |in> vector
     122              : !!  npwout=number of planewaves for given k point, for the |out> vector
     123              : !!  nspinor=number of spinorial components of the wavefunctions on current proc
     124              : !!  nspinortot=total number of spinorial components of the wavefunctions
     125              : !!  ntypat=number of types of atoms in cell
     126              : !!  only_SO=flag to calculate only the SO part in nonlop
     127              : !!  phkxredin(2,natom)=phase factors exp(2 pi kptin.xred)
     128              : !!  phkxredout(2,natom)=phase factors exp(2 pi kptout.xred)
     129              : !!  ph1d(2,3*(2*mgfft+1)*natom)=1D structure factors phase information
     130              : !!  ph3din(2,npwin,matblk)=3D structure factors, for each atom and plane wave (in)
     131              : !!  ph3dout(2,npwout,matblk)=3-dim structure factors, for each atom and plane wave (out)
     132              : !!  --- pspso removed in beautification because it was unused ---
     133              : !!  pspso(ntypat)=spin-orbit characteristic for each atom type
     134              : !!  -------------------------------------------------------------
     135              : !!  signs= if 1, get contracted elements (energy, forces, stress, ...)
     136              : !!         if 2, applies the non-local operator to a function in reciprocal space
     137              : !!  ucvol=unit cell volume (bohr^3)
     138              : !!  vectin(2,nspinor*npwin)=input cmplx wavefunction coefficients <G|Cnk>
     139              : !!  use_gbt= if 1, no spin-orbit coupling (scaler-Relativistic only);
     140              : !!           if 2, include only the \sigma_z component of the spin-orbit coupling.
     141              : !!
     142              : !! OUTPUT
     143              : !!  ==== if (signs==1) ====
     144              : !!     enlout(nnlout)= contribution of this state to the nl part
     145              : !!                     of the following properties:
     146              : !!       if choice=1 : enlout(1)               -> the energy
     147              : !!       if choice=2 : enlout(1:3*natom)       -> the forces
     148              : !!       if choice=3 : enlout(1:6)             -> the stresses
     149              : !!       if choice=23: enlout(1:6+3*natom)     -> the forces and the stresses
     150              : !!       if choice=4 : enlout(1:6*natom)       -> the frozen wf part of dynam. matrix
     151              : !!       if choice=6 : enlout(1:6*(3*natom+6)) -> the frozen wf part of elastic tensor
     152              : !!  ==== if (signs==2) ====
     153              : !!     vectout(2,nspinor*npwout)= result of the aplication of the nl operator
     154              : !!                                or one of its derivative to the input vect.:
     155              : !!       if choice=1 : Vnl |vectin>
     156              : !!       if choice=2 : dVnl/d(xred(idir,iatom) |vectin> (xred=reduced atm. pos.)
     157              : !!       if choice=3 : dVnl/d(strain(idir)) |vectin>    (symmetric strain =>idir=1...6)
     158              : !!       if choice=5 : dVnl/dk(idir) |vectin>           (k wavevector)
     159              : !!
     160              : !! NOTES
     161              : !! In the case signs=1, the array vectout is not used, nor modified
     162              : !! so that the same array as vectin can be used as a dummy argument;
     163              : !! the same is true for the pairs npwin-npwout, ffnlin-ffnlout,
     164              : !! kgin-kgout, ph3din-ph3dout, phkredin-phkxredout).
     165              : !!
     166              : !! Calculation includes contributions to grads of Etot wrt coord and
     167              : !! wrt strains for l=0,1,2,3.
     168              : !!
     169              : !! WARNINGS
     170              : !!  - Warning 1: This routine is in a transient state, during the
     171              : !!    time of the implementation of the spin-orbit coupling...
     172              : !!    In particular, the OMP parallelisation is still missing,
     173              : !!    but it matters here only when nspinor==2.
     174              : !!  - Warning 2: the order of atoms is governed by atindx
     175              : !!
     176              : !! PARENTS
     177              : !!      nonlop
     178              : !!
     179              : !! CHILDREN
     180              : !!      cont13,cont22,cont22cso,cont22so,cont24,cont3,cont33cso,cont33so,cont35
     181              : !!      contistr01,contistr03,contistr12,contstr21,contstr23,contstr25
     182              : !!      contstr25a,contstr26,ddkten,metcon,metcon_so,metric_so,metstr,opernl2
     183              : !!      opernl3,opernl4a,opernl4b,ph1d3d,scalewf_nonlop,strconv,strsocv,trace2
     184              : !!      xmpi_sum
     185              : !!
     186              : !! SOURCE
     187              : 
     188     88372944 : subroutine nonlop_pl(choice,dimekb1,dimekb2,dimffnlin,dimffnlout,ekb,enlout,&
     189     58915296 : &                     ffnlin,ffnlout,gmet,gprimd,idir,indlmn,ispin_gbt,istwf_k,kgin,kgout,kpgin,kpgout,&
     190              : &                     kptin,kptout,lmnmax,matblk,mgfft,mpi_enreg,mpsang,mpssoang,&
     191     29457648 : &                     natom,nattyp,ngfft,nkpgin,nkpgout,nloalg,npwin,npwout,nspinor,nspinortot,&
     192     29457648 : &                     ntypat,only_SO,phkxredin,phkxredout,ph1d,ph3din,ph3dout,signs,&
     193     29457648 : &                     spinaxis,ucvol,use_gbt,vectin,vectout)
     194              : 
     195              : !Arguments ------------------------------------
     196              : !This type is defined in defs_mpi
     197              : !The (inout) classification below is misleading; mpi_enreg is temporarily
     198              : ! changed but reset to its initial condition before exiting.
     199              : !scalars
     200              :  integer,intent(in) :: choice,dimekb1,dimekb2,dimffnlin,dimffnlout,idir,istwf_k,ispin_gbt
     201              :  integer,intent(in) :: lmnmax,matblk,mgfft,mpsang,mpssoang,natom,nkpgin,nkpgout
     202              :  integer,intent(in) :: npwin,npwout,nspinor,nspinortot,ntypat,only_SO,signs,use_gbt
     203              :  real(dp),intent(in) :: ucvol
     204              :  type(MPI_type),intent(in) :: mpi_enreg
     205              : !arrays
     206              :  integer,intent(in) :: indlmn(6,lmnmax,ntypat),kgin(3,npwin),kgout(3,npwout)
     207              :  integer,intent(in) :: nattyp(ntypat),ngfft(18),nloalg(3) !,pspso(ntypat) UNUSED
     208              :  real(dp),intent(in) :: ekb(dimekb1,dimekb2,nspinortot**2)
     209              :  real(dp),intent(in) :: ffnlin(npwin,dimffnlin,lmnmax,ntypat)
     210              :  real(dp),intent(in) :: ffnlout(npwout,dimffnlout,lmnmax,ntypat),gmet(3,3)
     211              :  real(dp),intent(in) :: gprimd(3,3),kpgin(npwin,nkpgin),kpgout(npwout,nkpgout)
     212              : !real(dp),intent(in) :: kptin(3),kptout(3),ph1d(2,3*(2*mgfft+1)*natom) !vz_d
     213              :  real(dp),intent(in) :: kptin(3),kptout(3) !vz_d
     214              :  real(dp),intent(in) :: ph1d(2,*),spinaxis(3) !vz_d
     215              :  real(dp),intent(in) :: phkxredin(2,natom),phkxredout(2,natom)
     216              :  real(dp),intent(inout) :: ph3din(2,npwin,matblk),ph3dout(2,npwout,matblk)
     217              :  real(dp),intent(inout) :: vectin(:,:)
     218              :  real(dp),intent(out) :: enlout(:) !vz_i
     219              :  real(dp),intent(inout) :: vectout(:,:) !vz_i
     220              : 
     221              : !Local variables-------------------------------
     222              : !mlang is the maximum number of different angular momenta
     223              : !(mlang=4 means s,p,d,f)
     224              : ! Note : in a future version, one should adjust mlang to mpsang.
     225              : !mlang2 is the maximum number of unique tensor components for a tensor
     226              : !of rank (mlang-1) with index range 1-3
     227              : !mlang3 is the maximum number of unique tensor components summed over
     228              : !all tensors of rank 0 through mlang-1.
     229              : !mlang4 is the total number of additional unique tensor components
     230              : !related to strain gradients, ranks 2 through mlang+1.
     231              : !mlang6 is the total number of additional unique tensor components
     232              : !related to strain 2nd derivaives, ranks 4 through mlang+3.
     233              : !mlang1 is the total number of certain additional unique tensor components
     234              : !related to internal strain, ranks 1 through mlang
     235              : !mlang5 is the total number of other additional unique tensor components
     236              : !related to internal strain, ranks 1 through mlang
     237              : !scalars
     238              :  integer,parameter :: mlang=4
     239              : ! MG: I tried to use parameters instead of saved variables but [tutorespfn][trf2_1] gets stuck on milou_g95_snofbfpe
     240              :  integer,save :: mlang1=((mlang+1)*(mlang+2)*(mlang+3))/6-1
     241              :  !integer,save :: mlang2=(mlang*(mlang+1))/2 ! Unused
     242              :  integer,save :: mlang3=(mlang*(mlang+1)*(mlang+2))/6
     243              :  integer,save :: mlang4=((mlang+2)*(mlang+3)*(mlang+4))/6-4
     244              :  integer,save :: mlang5=((mlang+3)*(mlang+4)*(mlang+5))/6-10
     245              :  integer,save :: mlang6=((mlang+4)*(mlang+5)*(mlang+6))/6-20
     246              :  integer :: compact,ia,ia1,ia2,ia3,ia4,ia5,ierr,iest,ig,ii,ilang,ilang2,ilmn
     247              :  integer :: iln,iln0,indx,iproj,ipsang,ishift,isp,ispin,ispinor,ispinor_index,ispinp,ispinor_ekb
     248              :  integer :: istr,istr1,istr2,iterm,itypat,jj,jjk,jjs,jjs1,jjs2,jjs3,jjs4,jjstr,jspin
     249              :  integer :: mincat,mproj,mu,mumax,n1,n2,n3,ndgxdt,ndgxdtfac,nincat,nlang
     250              :  integer :: nproj,nspinso,rank
     251              :  integer :: sign,spaceComm,  isft
     252              :  real(dp) :: alpha,beta,e2nl,e2nldd,enlk
     253              :  character(len=500) :: msg
     254              : !arrays
     255     29457648 :  integer,allocatable :: indlmn_s(:,:,:),jproj(:)
     256              :  real(dp) :: amet(2,3,3,2,2),amet_lo(3,3),e2nl_tmp(6),eisnl(3),rank2(6)
     257              :  real(dp) :: rank2c(2,6),soc_weight(3),strsnl(6),strsnl_out(6),strsso(6,3),strssoc(6),trace(2)!,tsec(2)
     258     29457648 :  real(dp),allocatable :: d2gxdis(:,:,:,:,:),d2gxdis_s(:,:,:,:)
     259     29457648 :  real(dp),allocatable :: d2gxds2(:,:,:,:,:),d2gxds2_s(:,:,:,:)
     260     29457648 :  real(dp),allocatable :: dgxdis(:,:,:,:,:),dgxdis_s(:,:,:,:),dgxds(:,:,:,:,:)
     261     29457648 :  real(dp),allocatable :: dgxds_s(:,:,:,:),dgxdsfac(:,:,:,:,:)
     262     29457648 :  real(dp),allocatable :: dgxdt(:,:,:,:,:,:),dgxdt_s(:,:,:,:,:)
     263     29457648 :  real(dp),allocatable :: dgxdtfac(:,:,:,:,:),ekb_s(:,:),gxa(:,:,:,:,:)
     264     29457648 :  real(dp),allocatable :: gxa_s(:,:,:,:),gxafac(:,:,:,:),pauli(:,:,:,:)
     265     29457648 :  real(dp),allocatable :: temp(:,:),tmpfac(:,:),vectin_s(:,:),vectout_s(:,:)
     266     29457648 :  real(dp),allocatable :: wt(:,:)
     267              : 
     268              : ! **********************************************************************
     269              : 
     270              :  ABI_UNUSED(mgfft)
     271              : 
     272              : !Test: spin orbit not allowed for choice=5,6
     273     29457648 :  if (nspinortot==2 .and. choice==6 ) then
     274            0 :    ABI_BUG('For nspinortot=2, choice=6 is not yet allowed.')
     275              :  end if
     276              : 
     277     29457648 :  if ((choice<1 .or. choice>6) .and. choice/=23 ) then
     278            0 :    write(msg,'(a,i0)')'Does not presently support this choice=',choice
     279            0 :    ABI_BUG(msg)
     280              :  end if
     281              : 
     282              : !Test: choice 51 and 52 only allowed with nonlop_ylm
     283              : !JWZ, 01-Sep-08
     284     29457648 :  if (choice==51 .or. choice==52) then
     285            0 :    ABI_BUG('choice 51 or 52 is not yet allowed.')
     286              :  end if
     287              : 
     288              : !Define dimension of work arrays.
     289     71836647 :  mincat=min(NLO_MINCAT,maxval(nattyp))
     290    270290592 :  mproj=maxval(indlmn(3,:,:))
     291     88372944 :  ABI_MALLOC(temp,(2,mlang4))
     292     58915296 :  ABI_MALLOC(tmpfac,(2,mlang4))
     293     88372944 :  ABI_MALLOC(wt,(mlang,mproj))
     294     29457648 :  ABI_MALLOC(jproj,(mlang))
     295     29457648 :  n1=ngfft(1) ; n2=ngfft(2) ; n3=ngfft(3)
     296     58915296 :  ABI_MALLOC(ekb_s,(mlang,mproj))
     297    117830592 :  ABI_MALLOC(indlmn_s,(6,lmnmax,ntypat))
     298              : 
     299              : !Eventually compute the spin-orbit metric tensor:
     300     29457648 :  if (mpssoang>mpsang) then
     301      2339994 :    ABI_MALLOC(pauli,(2,2,2,3))
     302      9359976 :    soc_weight = one
     303              : ! GBT: keep only the z-component, optionally flip its sign
     304      2339994 :    if (use_gbt == 2) then
     305        47388 :      soc_weight(1:2) = 0
     306        15796 :      if (ispin_gbt == 2) soc_weight(3) = -1
     307              :    end if
     308      2339994 :    call geteuler(spinaxis,alpha,beta)
     309      2339994 :    call metric_so(amet,soc_weight,gprimd,pauli,alpha,beta)
     310              :  end if
     311              : 
     312              : !Allocate array gxa (contains projected scalars).
     313    176745888 :  ABI_MALLOC(gxa,(2,mlang3,mincat,mproj,nspinortot))
     314     29457648 :  if(nspinor==2)  then
     315      7760870 :    ABI_MALLOC(gxa_s,(2,mlang3,mincat,mproj))
     316              :  else
     317     27905474 :    ABI_MALLOC(gxa_s,(0,0,0,0))
     318              :  end if
     319              : 
     320    147288240 :  ABI_MALLOC(gxafac,(2,mlang3,mincat,mproj))
     321   5618103892 :  gxa(:,:,:,:,:)=zero
     322              : 
     323              : !If choice==2 : first-order atomic displacements
     324              : !If signs==2, only one direction is considered
     325              : !If signs==1, the three directions are considered
     326              : !If choice==4 and signs==1 : second-order atomic displacements,
     327              : !the nine components are considered
     328              : !If choice==5 and signs==2 : ddk
     329              : !component 1 -> from ffnl(:,2,...)
     330              : !component 2 -> from ffnl(:,1,...) (too much space is booked for this
     331              : !case, since the number of angular momenta is smaller than mlang3, but it is easier)
     332     29457648 :  ndgxdt=0
     333     29457648 :  if(signs==2 .and. choice==2) ndgxdt=1
     334     29457648 :  if(signs==1 .and. (choice==2.or.choice==23)) ndgxdt=3
     335     29457648 :  if(choice==4) ndgxdt=9
     336     29457648 :  if(choice==5) ndgxdt=2
     337              : !Allocate dgxdt (contains derivatives of gxa with respect to atomic displacements or ddk).
     338    206203536 :  ABI_MALLOC(dgxdt,(2,ndgxdt,mlang3,mincat,mproj,nspinortot))
     339   3068408272 :  dgxdt(:,:,:,:,:,:)=zero
     340     29457648 :  if(nspinor==2)then
     341      9313044 :    ABI_MALLOC(dgxdt_s,(2,ndgxdt,mlang3,mincat,mproj))
     342    432512190 :    dgxdt_s(:,:,:,:,:)=zero
     343              :  else
     344     27905474 :    ABI_MALLOC(dgxdt_s,(0,0,0,0,0))
     345              :  end if
     346     29457648 :  ndgxdtfac=0
     347     29457648 :  if(signs==2 .and. choice==2) ndgxdtfac=1
     348     29457648 :  if(choice==4) ndgxdtfac=3
     349     29457648 :  if(choice==5) ndgxdtfac=2
     350    176745888 :  ABI_MALLOC(dgxdtfac,(2,ndgxdtfac,mlang3,mincat,mproj))
     351              : 
     352              : !Allocate dgxds (contains derivatives of gxa with respect to strains).
     353    176745888 :  ABI_MALLOC(dgxds,(2,mlang4,mincat,mproj,nspinor))
     354  14275266580 :  dgxds(:,:,:,:,:)=zero
     355    147288240 :  ABI_MALLOC(dgxdsfac,(2,mlang4,mincat,mproj,nspinor))
     356     29457648 :  if(choice==6) then
     357       126192 :    ABI_MALLOC(dgxdis,(2,mlang1,mincat,mproj,nspinor))
     358       126192 :    ABI_MALLOC(d2gxdis,(2,mlang5,mincat,mproj,nspinor))
     359       126192 :    ABI_MALLOC(d2gxds2,(2,mlang6,mincat,mproj,nspinor))
     360              :  else
     361     29436616 :    ABI_MALLOC(dgxdis ,(0,0,0,0,0))
     362     29436616 :    ABI_MALLOC(d2gxdis,(0,0,0,0,0))
     363     29436616 :    ABI_MALLOC(d2gxds2,(0,0,0,0,0))
     364              :  end if
     365     29457648 :  ABI_MALLOC(dgxds_s  ,(0,0,0,0))
     366     29457648 :  ABI_MALLOC(dgxdis_s ,(0,0,0,0))
     367     29457648 :  ABI_MALLOC(d2gxdis_s,(0,0,0,0))
     368     29457648 :  ABI_MALLOC(d2gxds2_s,(0,0,0,0))
     369     29457648 :  if(nspinor==2)then
     370      1552174 :    ABI_FREE(dgxds_s)
     371      7760870 :    ABI_MALLOC(dgxds_s,(2,mlang4,mincat,mproj))
     372   2410320282 :    dgxds_s(:,:,:,:)=zero
     373      1552174 :    if(choice==6) then
     374            0 :      ABI_FREE(dgxdis_s)
     375            0 :      ABI_FREE(d2gxdis_s)
     376            0 :      ABI_FREE(d2gxds2_s)
     377            0 :      ABI_MALLOC(dgxdis_s,(2,mlang1,mincat,mproj))
     378            0 :      ABI_MALLOC(d2gxdis_s,(2,mlang5,mincat,mproj))
     379            0 :      ABI_MALLOC(d2gxds2_s,(2,mlang6,mincat,mproj))
     380              :    else
     381              :    end if
     382              :  end if
     383              : 
     384              : !Zero out some arrays
     385     47247716 :  if(choice==2 .or. choice==4 .or. choice==5 .or. choice==6 .or. choice==23) enlout(:)=0.0d0
     386              : 
     387  28490720499 :  if(signs==2) vectout(:,:)=zero
     388              : 
     389              :  !if(choice==3.or.choice==23) then
     390              :  !  strsnl(:)=zero
     391              :  !  if(mpssoang>mpsang) strsso(:,:)=zero
     392              :  !end if
     393     29457648 :  enlk=zero
     394     29457648 :  strsso = zero
     395     29457648 :  strsnl = zero
     396              : 
     397              : !In the case vectin is a spinor, split its second part.
     398              : !Also, eventually take into account the storage format of the wavefunction
     399              : !(the original vector will be restored before leaving the routine,
     400              : !except for the vectin(2,1) component with istwf_k==2,
     401              : !that should vanish)
     402              : !In sequential, treat the second spinor part first
     403     29457648 :  if (nspinor==2)then
     404      4656522 :    ABI_MALLOC(vectin_s,(2,npwin))
     405      4656522 :    ABI_MALLOC(vectout_s,(2,npwout))
     406              : 
     407      1552174 :    isft = npwin;if (mpi_enreg%nproc_spinor>1) isft=0
     408              : 
     409              : !  Initialize it
     410              : !$OMP PARALLEL DO
     411    329881518 :    do ig=1,npwin
     412    328329344 :      vectin_s(1,ig)=vectin(1,ig+isft)
     413    329881518 :      vectin_s(2,ig)=vectin(2,ig+isft)
     414              :    end do
     415              : 
     416              : !  Take into account the storage
     417      1552174 :    if(istwf_k/=1)then
     418            0 :      call scalewf_nonlop(istwf_k,mpi_enreg,npwin,1,vectin_s)
     419              :    end if
     420              :  end if ! nspinortot==2
     421              : 
     422              : !Treat the first spinor part now
     423     29457648 :  if(istwf_k/=1) then
     424       904765 :    call scalewf_nonlop(istwf_k,mpi_enreg,npwin,1,vectin)
     425              :  end if
     426              : 
     427              : 
     428              : !Big loop on atom types.
     429     29457648 :  ia1=1
     430     71836647 :  do itypat=1,ntypat
     431              : 
     432              : !  Get atom loop indices for different types:
     433     42378999 :    ia2=ia1+nattyp(itypat)-1
     434              : 
     435              : !  Cut the sum on different atoms in blocks, to allow memory saving.
     436              : !  Inner summations on atoms will be done from ia3 to ia4.
     437              : !  Note that the maximum range from ia3 to ia4 is mincat (maximum
     438              : !  increment of atoms).
     439     85163057 :    do ia3=ia1,ia2,mincat
     440     42784058 :      ia4=min(ia2,ia3+mincat-1)
     441              : !    Give the increment of number of atoms in this subset.
     442     42784058 :      nincat=ia4-ia3+1
     443              : 
     444              : !    Prepare the phase factors for the atoms between ia3 and ia4 :
     445              : !    For nloalg(2)<=0, they were not prepared previously,it is needed to
     446              : !    compute them again.
     447     42784058 :      if(nloalg(2)<=0)then
     448              : !      For nloalg(2)==0, it is needed to compute the phase factors.
     449      2243368 :        if(mincat>matblk)then
     450              :          write(msg,'(a,a,a,i4,a,i4,a)')&
     451            0 :           'With nloc_mem<=0, mincat must be less than matblk.',ch10,&
     452            0 :           'Their value is ',mincat,' and ',matblk,'.'
     453            0 :          ABI_BUG(msg)
     454              :        end if
     455      2243368 :        call ph1d3d(ia3,ia4,kgin,matblk,natom,npwin,n1,n2,n3,phkxredin,ph1d,ph3din)
     456              :      end if
     457              : 
     458              : !    Here begins the different treatment for the scalar-relativistic
     459              : !    part(s) and the spin-orbit part.
     460              : !    Loop on ispinor : 1 for scalar-Relativistic, 2 for spin-orbit
     461     42784058 :      nspinso=1;if (mpssoang>mpsang) nspinso=2
     462              : 
     463              :      ! Change nspinso if collinear run or if nspinor == 2 and SOC is not wanted.
     464              :      ! TODO: The last check requires pspso
     465     42784058 :      if (nspinortot == 1 .and. use_gbt /= 2) nspinso = 1
     466              : 
     467    130403329 :      do ispinor=1,nspinso
     468     45240272 :        ispinor_index=ispinor
     469     45240272 :        if (mpi_enreg%paral_spinor==1) ispinor_index=mpi_enreg%me_spinor+1
     470              : 
     471              : !
     472              : !      mjv 25 6 2008: if only_SO == 1 or 2 skip the scalar relativistic terms
     473              : !      only output the spin orbit ones
     474              : !
     475     45240272 :        if (ispinor==1 .and. only_SO>0) cycle
     476              : 
     477              : !      Select scalar-relativistic or spin-orbit KB-energies:
     478    901451054 :        ekb_s(:,:)=zero ; wt(:,:)=zero
     479              : !      Loop over (l,n) values (loop over l,m,n and test on l,n)
     480    226201360 :        iln0=0 ; jproj(:)=0 ; nlang=0
     481   1675401805 :        indlmn_s(:,:,itypat)=0
     482    278120491 :        do ilmn=1,lmnmax
     483    232880219 :          if(ispinor/=indlmn(6,ilmn,itypat))cycle
     484   1218826266 :          indlmn_s(:,ilmn,itypat)=indlmn(:,ilmn,itypat)
     485    174118038 :          iln =indlmn(5,ilmn,itypat)
     486    219358310 :          if (iln>iln0) then
     487    174118038 :            iln0=iln
     488    174118038 :            ipsang=indlmn(1,ilmn,itypat)+1
     489              : !          DEBUG
     490              : !          write(std_out,*)' nonlop : ipsang,ilmn,itypat,ispinor=',ipsang,ilmn,itypat,ispinor
     491              : !          ENDDEBUG
     492    174118038 :            iproj=indlmn(3,ilmn,itypat)
     493              : !          This shift is not needed anymore
     494              : !          if (ispinor==2) ipsang=indlmn(1,ilmn,itypat)-mpsang+2
     495              : !           ekb_s(ipsang,iproj)=ekb(iln,itypat,ispinor)
     496    174118038 :            ispinor_ekb=min(ispinor,ubound(ekb,3))
     497    174118038 :            ekb_s(ipsang,iproj)=ekb(iln,itypat,ispinor_ekb)
     498    174118038 :            wt(ipsang,iproj)=4.d0*pi/ucvol*dble(2*ipsang-1)*ekb_s(ipsang,iproj)
     499              : !
     500              : !          mjv 27 6 2008: if only_SO == 2 remove the factor of l in the operator
     501              : !
     502    174118038 :            if (only_SO == 2) then
     503            0 :              wt(ipsang,iproj)=4.d0*pi/ucvol*ekb_s(ipsang,iproj)
     504              :            end if
     505    174118038 :            jproj(ipsang)=max(jproj(ipsang),iproj)
     506    174118038 :            if(iproj>0)nlang=max(nlang,ipsang)
     507              :          end if
     508              :        end do ! ilmn
     509              : 
     510              : 
     511              : !      If nlang is not 0, then some non-local part is to be applied for that type of atom.
     512     88024330 :        if (nlang/=0) then
     513              : !        Operate with the non-local potential on the wavefunction, in order
     514              : !        to get projected quantities. Call different routines opernl2,
     515              : !        opernl3, opernl4x which corresponds to different writings of the
     516              : !        same numerical operations. There is still optimisation left for
     517              : !        the case istwf_k/=1 (up to a factor 2 in speed).
     518              : !        call timab(74+choice,1,tsec)
     519     43565098 :          sign=1
     520  12632044519 :          gxa(:,:,:,:,:)=zero
     521   6143043699 :          dgxdt(:,:,:,:,:,:)=zero
     522  32197922983 :          dgxds(:,:,:,:,:)=zero
     523              : 
     524              : !        Only the first spinorial component of vectin is taken into account first
     525     43565098 :          ispin=1;if (mpi_enreg%paral_spinor==1) ispin=ispinor_index
     526     43565098 :          if(nloalg(1)==2) then
     527              :            call opernl2(choice,dgxdis,dgxds,d2gxdis,d2gxds2,dgxdt,&
     528              : &           ffnlin,gmet,gxa,ia3,idir,indlmn_s,ispinor,istwf_k,itypat,&
     529              : &           jproj,kgin,kpgin,kptin,lmnmax,matblk,mincat,mlang1,mlang3,mlang4,&
     530              : &           mlang5,mlang6,mproj,ndgxdt,dimffnlin,nincat,nkpgin,nlang,nloalg,npwin,&
     531        10474 : &           ntypat,ph3din,sign,vectin)
     532     43554624 :          else if(nloalg(1)==3) then
     533              :            call opernl3(choice,dgxdis,dgxds,d2gxdis,d2gxds2,dgxdt,&
     534              : &           ffnlin,gmet,gxa,ia3,idir,indlmn_s,ispinor,istwf_k,itypat,&
     535              : &           jproj,kgin,kpgin,kptin,lmnmax,matblk,mincat,mlang1,mlang3,mlang4,&
     536              : &           mlang5,mlang6,mproj,ndgxdt,dimffnlin,nincat,nkpgin,nlang,nloalg,npwin,&
     537       126990 : &           ntypat,ph3din,sign,vectin)
     538     43427634 :          else if(nloalg(1)==4) then
     539              :            call opernl4a(choice,dgxdis,dgxds,d2gxdis,d2gxds2,dgxdt,&
     540              : &           ffnlin,gmet,gxa,ia3,idir,indlmn_s,ispinor,istwf_k,itypat,&
     541              : &           jproj,kgin,kpgin,kptin,lmnmax,matblk,mincat,mlang1,mlang3,mlang4,&
     542              : &           mlang5,mlang6,mproj,ndgxdt,dimffnlin,nincat,nkpgin,nlang,nloalg,npwin,&
     543     43427634 : &           ntypat,ph3din,vectin)
     544              :          end if
     545              : !        This duplication of the opernl calls is needed to avoid copying
     546              : !        vectin, with a detrimental effect on speed.
     547     43565098 :          if (nspinor==2)then
     548      4901725 :            ispin=2
     549      4901725 :            if(nloalg(1)==2) then
     550              :              call opernl2(choice,dgxdis_s,dgxds_s,d2gxdis_s,d2gxds2_s,dgxdt_s,&
     551              : &             ffnlin,gmet,gxa_s,ia3,idir,indlmn_s,ispinor,istwf_k,itypat,&
     552              : &             jproj,kgin,kpgin,kptin,lmnmax,matblk,mincat,mlang1,mlang3,mlang4,&
     553              : &             mlang5,mlang6,mproj,ndgxdt,dimffnlin,nincat,nkpgin,nlang,nloalg,npwin,&
     554            0 : &             ntypat,ph3din,sign,vectin_s)
     555      4901725 :            else if(nloalg(1)==3) then
     556              :              call opernl3(choice,dgxdis_s,dgxds_s,d2gxdis_s,d2gxds2_s,dgxdt_s,&
     557              : &             ffnlin,gmet,gxa_s,ia3,idir,indlmn_s,ispinor,istwf_k,itypat,&
     558              : &             jproj,kgin,kpgin,kptin,lmnmax,matblk,mincat,mlang1,mlang3,mlang4,&
     559              : &             mlang5,mlang6,mproj,ndgxdt,dimffnlin,nincat,nkpgin,nlang,nloalg,npwin,&
     560            0 : &             ntypat,ph3din,sign,vectin_s)
     561      4901725 :            else if(nloalg(1)==4) then
     562              :              call opernl4a(choice,dgxdis_s,dgxds_s,d2gxdis_s,d2gxds2_s,dgxdt_s,&
     563              : &             ffnlin,gmet,gxa_s,ia3,idir,indlmn_s,ispinor,istwf_k,itypat,&
     564              : &             jproj,kgin,kpgin,kptin,lmnmax,matblk,mincat,mlang1,mlang3,mlang4,&
     565              : &             mlang5,mlang6,mproj,ndgxdt,dimffnlin,nincat,nkpgin,nlang,nloalg,npwin,&
     566      4901725 : &             ntypat,ph3din,vectin_s)
     567              :            end if
     568   9104999873 :            dgxds(:,:,:,:,ispin)=dgxds_s(:,:,:,:)
     569   1541116165 :            dgxdt(:,:,:,:,:,ispin)=dgxdt_s(:,:,:,:,:)
     570   3552064865 :            gxa(:,:,:,:,ispin)=gxa_s(:,:,:,:)
     571              :          end if
     572              : 
     573              : !        Parallelism stuff
     574     43565098 :          spaceComm=mpi_enreg%comm_fft
     575     43565098 :          call xmpi_sum(dgxds,spaceComm,ierr)
     576     43565098 :          if (mpi_enreg%paral_spinor==1) then
     577        19712 :            spaceComm=mpi_enreg%comm_spinorfft
     578        19712 :            jspin=3-ispin
     579      4908288 :            gxa(:,:,:,:,ispin)=gxa(:,:,:,:,1)
     580      4908288 :            gxa(:,:,:,:,jspin)=zero
     581        19712 :            if ( ndgxdt>0)then
     582       155328 :              dgxdt(:,:,:,:,:,ispin)=dgxdt(:,:,:,:,:,1)
     583       155328 :              dgxdt(:,:,:,:,:,jspin)=zero
     584              :            end if
     585              :          end if
     586              : 
     587     43565098 :          call xmpi_sum(gxa,spaceComm,ierr)
     588     43565098 :          if(ndgxdt>0) then
     589      6998360 :            call xmpi_sum(dgxdt,spaceComm,ierr)
     590              :          end if
     591              : 
     592              : !        XG030513 : MPIWF, at this place, one should perform the reduction
     593              : !        and spread of data of gxa, dgxdt and dgxds
     594              : 
     595              : 
     596              : 
     597              : ! BUG FIX START
     598              : !        MS100725: First loop over spins, ilang, proj to take care of the ddk
     599              : !        decompaction PRIOR to entering the main loop. This fixes a subtle bug
     600              : !        in the calculation of the velocity operator with SOC
     601     92031921 :          do isp=1,nspinor
     602     48466823 :            ispin=isp;if (mpi_enreg%paral_spinor==1) ispin=ispinor_index
     603              : 
     604    167556628 :            do ia=1,nincat
     605    315037219 :              do ilang=1,nlang
     606    191045689 :                nproj=jproj(ilang)
     607    266570396 :                if(nproj/=0) then
     608    176785943 :                  ilang2=(ilang*(ilang+1))/2
     609    506152007 :                  do iproj=1,nproj
     610              : 
     611              : !                  The rank of the tensor gxa equals l:
     612    329366064 :                    rank=ilang-1
     613              : !                  jjs gives the starting address of the relevant components
     614    329366064 :                    jjs=1+((ilang-1)*ilang*(ilang+1))/6
     615    329366064 :                    if (ilang>4) then
     616            0 :                      write(msg,'(a,i0)')' ilang must fall in range [1..4] but value is ',ilang
     617            0 :                      ABI_BUG(msg)
     618              :                    end if
     619              : 
     620              : !                  Eventual tensorial decompaction for ddk perturbation:
     621    506152007 :                    if(choice==5 .and. ilang>=2) then
     622      4330797 :                      jjk=1+((ilang-2)*(ilang-1)*ilang)/6
     623      4330797 :                      compact=-1
     624              :                      temp(:,1:(rank*(rank+1))/2)= &
     625     28351860 : &                     dgxdt(:,2,jjk:jjk-1+(rank*(rank+1))/2,ia,iproj,ispin)
     626      4330797 :                      call ddkten(compact,idir,rank,temp,tmpfac)
     627              :                      dgxdt(:,1,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj,ispin)=&
     628              : &                     dgxdt(:,1,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj,ispin)&
     629     59845908 : &                     +tmpfac(:,1:((rank+1)*(rank+2))/2)
     630              :                     end if
     631              : 
     632              : !                  End loop over iproj:
     633              :                  end do
     634              : !                End condition of existence of a reference state:
     635              :                end if
     636              : 
     637              : !              End loop over ilang:
     638              :              end do
     639              : 
     640              : !            End loop over ia:
     641              :            end do
     642              : 
     643              : !            End loop over isp
     644              :          end do
     645              : ! BUG FIX END
     646              : 
     647              : 
     648              : !        Main loop over spins:
     649     92031921 :          do isp=1,nspinor
     650     48466823 :            ispin=isp;if (mpi_enreg%paral_spinor==1) ispin=ispinor_index
     651              : 
     652              : !          Perform contractions for the various tensors (d)gx?, producing the
     653              : !          contracted tensors (d)gx?fac to be passed back to opernl:
     654    123991530 :            do ia=1,nincat
     655    315037219 :              do ilang=1,nlang
     656    191045689 :                nproj=jproj(ilang)
     657    266570396 :                if(nproj/=0) then
     658    176785943 :                  ilang2=(ilang*(ilang+1))/2
     659    506152007 :                  do iproj=1,nproj
     660              : 
     661              : !                  The rank of the tensor gxa equals l:
     662    329366064 :                    rank=ilang-1
     663              : !                  jjs gives the starting address of the relevant components
     664    329366064 :                    jjs=1+((ilang-1)*ilang*(ilang+1))/6
     665    329366064 :                    if (ilang>4) then
     666            0 :                      write(msg,'(a,i0)')' ilang must fall in range [1..4] but value is ',ilang
     667            0 :                      ABI_BUG(msg)
     668              :                    end if
     669              : 
     670              : !                  Metric & spinorial contraction from gxa to gxafac. The treatment
     671              : !                  is different for the scalar-relativistic and spin-orbit parts.
     672    329366064 :                    if(ispinor==1) then
     673              : !                    ------ Scalar-Relativistic ------
     674              :                      temp(:,1:((rank+1)*(rank+2))/2)= &
     675   2592208547 : &                     gxa(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj,ispin)
     676    264173618 :                      call metcon(rank,gmet,temp,tmpfac)
     677              :                      gxafac(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj)= &
     678   2592208547 : &                     wt(ilang,iproj)*tmpfac(:,1:((rank+1)*(rank+2))/2)
     679              :                    else
     680              : !                    ------ Spin-orbit ------
     681    924560782 :                      gxafac(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj)=zero
     682              : !                    Contraction over spins:
     683    195529950 :                      do ispinp=1,nspinortot
     684              : !                        => Imaginary part (multiplying by i, then by the Im of amet):
     685              :                          temp(1,1:((rank+1)*(rank+2))/2)= &
     686    703060176 : &                         -gxa(2,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj,ispinp)
     687              :                          temp(2,1:((rank+1)*(rank+2))/2)= &
     688    703060176 : &                          gxa(1,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj,ispinp)
     689   1694387552 :                          amet_lo(:,:)=amet(2,:,:,ispin,ispinp)
     690    130337504 :                          call metcon_so(rank,gmet,amet_lo,temp,tmpfac)
     691              :                          gxafac(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj)= &
     692              : &                         gxafac(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj)+ &
     693   1848505520 : &                         wt(ilang,iproj)*tmpfac(:,1:((rank+1)*(rank+2))/2)
     694              : !                        => Real part:
     695              :                          temp(:,1:((rank+1)*(rank+2))/2)= &
     696   1848505520 : &                         gxa(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj,ispinp)
     697   1694387552 :                          amet_lo(:,:)=amet(1,:,:,ispin,ispinp)
     698    130337504 :                          call metcon_so(rank,gmet,amet_lo,temp,tmpfac)
     699              :                          gxafac(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj)= &
     700              : &                         gxafac(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj)+ &
     701   1913697966 : &                         wt(ilang,iproj)*tmpfac(:,1:((rank+1)*(rank+2))/2)
     702              :                      end do
     703              :                    end if
     704              : 
     705              : !                  Eventual tensorial compaction of gxafac for ddk
     706              : !                  perturbation:
     707    329366064 :                    if(choice==5 .and. ilang>=2) then
     708      4330797 :                      jjk=1+((ilang-2)*(ilang-1)*ilang)/6
     709              : ! BUG FIX START
     710              : ! MS100725: Moved this chunk of code to a separate preliminary loop (see above),
     711              : !           to fix the k-derivative of the SOC Hamiltonian
     712              : !                     compact=-1
     713              : !                     temp(:,1:(rank*(rank+1))/2)= &
     714              : !&                     dgxdt(:,2,jjk:jjk-1+(rank*(rank+1))/2,ia,iproj,ispin)
     715              : !                     call ddkten(compact,idir,rank,temp,tmpfac)
     716              : !                     dgxdt(:,1,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj,ispin)= &
     717              : !&                     dgxdt(:,1,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj,ispin)&
     718              : !&                     +tmpfac(:,1:((rank+1)*(rank+2))/2)
     719              : ! BUG FIX END
     720      4330797 :                      compact=1
     721              :                      tmpfac(:,1:((rank+1)*(rank+2))/2)= &
     722     59845908 : &                     gxafac(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj)
     723      4330797 :                      call ddkten(compact,idir,rank,temp,tmpfac)
     724              :                      dgxdtfac(:,2,jjk:jjk-1+(rank*(rank+1))/2,ia,iproj)= &
     725     28351860 : &                     temp(:,1:(rank*(rank+1))/2)
     726              :                    end if
     727              : 
     728              : !                  Section for strain perturbation
     729              : !                  no spin-orbit yet
     730              : 
     731    329366064 :                    if(choice==3 .and. signs==2) then
     732      4843316 :                      istr=idir
     733      4843316 :                      if(ispinor==1) then
     734              : !                      ------ Scalar-Relativistic ------
     735              : !                      jjstr is the starting address for dgxds and dgxdsfac
     736      4843316 :                        jjstr=-3+((ilang+1)*(ilang+2)*(ilang+3))/6
     737              : !                      diagonal enlk contribution
     738              : !                      note sign change (12/05/02)
     739      4843316 :                        if(istr>3) then
     740     27251968 :                          gxafac(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj)=zero
     741              :                        else
     742              :                          gxafac(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj)=&
     743     25344412 : &                         -gxafac(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj)
     744              :                        end if
     745    153764492 :                        dgxdsfac(:,jjstr:jjstr-1+((rank+3)*(rank+4))/2,ia,iproj,isp)=zero
     746      4843316 :                        iterm=1
     747              :                        temp(:,1:((rank+1)*(rank+2))/2)= &
     748     52596380 : &                       gxa(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj,ispin)
     749      4843316 :                        call metstr(istr,rank,iterm,gmet,gprimd,temp,tmpfac)
     750              :                        dgxdsfac(:,jjstr:jjstr-1+((rank+3)*(rank+4))/2,ia,iproj,isp)= &
     751    153764492 : &                       wt(ilang,iproj)*tmpfac(:,1:((rank+3)*(rank+4))/2)
     752      4843316 :                        iterm=2
     753              :                        temp(:,1:((rank+1)*(rank+2))/2)= &
     754     52596380 : &                       gxa(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj,ispin)
     755      4843316 :                        call metstr(istr,rank,iterm,gmet,gprimd,temp,tmpfac)
     756              :                        gxafac(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj)= &
     757              : &                       +gxafac(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj)+ &
     758     52596380 : &                       wt(ilang,iproj)*tmpfac(:,1:((rank+1)*(rank+2))/2)
     759      4843316 :                        iterm=3
     760              :                        temp(:,1:((rank+3)*(rank+4))/2)= &
     761    153764492 :                        dgxds(:,jjstr:jjstr-1+((rank+3)*(rank+4))/2,ia,iproj,isp)
     762      4843316 :                        call metstr(istr,rank,iterm,gmet,gprimd,temp,tmpfac)
     763              :                        gxafac(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj)= &
     764              : &                       gxafac(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj)+ &
     765     52596380 : &                       wt(ilang,iproj)*tmpfac(:,1:((rank+1)*(rank+2))/2)
     766              :                      end if
     767              : !                    end section for strain perturbation
     768              :                    end if
     769              : 
     770              : !                  Eventual metric & spinorial contraction from dgxdt to dgxdtfac.
     771              : !                  either for the dynamical matrix, or for the application of the
     772              : !                  gradient of the operator. The treatment is different for the
     773              : !                  scalar-relativistic and spin-orbit parts.
     774              :                    if ((choice==2.and.signs==2).or. &
     775    329366064 : &                   (choice==5.and.signs==2).or. &
     776              : &                   (choice==4)) then
     777     30000616 :                      mumax=ndgxdtfac;if (choice==5) mumax=1
     778     61955096 :                      do mu=1,mumax
     779    361320544 :                        if(ispinor==1) then
     780              : !                        ------ Scalar-Relativistic ------
     781              :                          temp(:,1:((rank+1)*(rank+2))/2)= &
     782    264791350 : &                         dgxdt(:,mu,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj,ispin)
     783     27972016 :                          call metcon(rank,gmet,temp,tmpfac)
     784              :                          dgxdtfac(:,mu,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj)=&
     785    264791350 : &                         wt(ilang,iproj)*tmpfac(:,1:((rank+1)*(rank+2))/2)
     786              :                        else
     787              : !                        ------ Spin-orbit ------
     788     56174976 :                          dgxdtfac(:,mu,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj)=zero
     789              : !                        Contraction over spins:
     790     11947392 :                          do ispinp=1,nspinortot
     791              : !                          => Imaginary part (multiplying by i, then by the Im of amet):
     792              :                            temp(1,1:((rank+1)*(rank+2))/2)= &
     793     42759936 : &                           -dgxdt(2,mu,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj,ispinp)
     794              :                            temp(2,1:((rank+1)*(rank+2))/2)= &
     795     42759936 : &                           dgxdt(1,mu,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj,ispinp)
     796    103544064 :                            amet_lo(:,:)=amet(2,:,:,ispin,ispinp)
     797      7964928 :                            call metcon_so(rank,gmet,amet_lo,temp,tmpfac)
     798              :                            dgxdtfac(:,mu,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj)=&
     799              : &                           dgxdtfac(:,mu,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj)+&
     800    112349952 : &                           wt(ilang,iproj)*tmpfac(:,1:((rank+1)*(rank+2))/2)
     801              : !                          => Real part:
     802              :                            temp(:,1:((rank+1)*(rank+2))/2)= &
     803    112349952 : &                           dgxdt(:,mu,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj,ispinp)
     804    103544064 :                            amet_lo(:,:)=amet(1,:,:,ispin,ispinp)
     805      7964928 :                            call metcon_so(rank,gmet,amet_lo,temp,tmpfac)
     806              :                            dgxdtfac(:,mu,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj)=&
     807              : &                           dgxdtfac(:,mu,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj)+&
     808    116332416 : &                           wt(ilang,iproj)*tmpfac(:,1:((rank+1)*(rank+2))/2)
     809              :                          end do
     810              :                        end if
     811              :                      end do
     812              :                    end if
     813              : 
     814              : 
     815              : !                  ----  Accumulate the nonlocal energy.
     816   1391833819 :                    do ii=1,ilang2
     817   1062467755 :                      jj=ii-1+jjs
     818              :                      enlk=enlk+(gxafac(1,jj,ia,iproj)*gxa(1,jj,ia,iproj,ispin)&
     819   1391833819 : &                     +gxafac(2,jj,ia,iproj)*gxa(2,jj,ia,iproj,ispin) )
     820              :                    end do
     821              : 
     822              : !                  ----  Accumulate force contributions if requested.
     823              : !                  Note that the contraction of gxa with dgxdt can be done like
     824              : !                  a cartesian dot product now because the symmetrically-related
     825              : !                  terms are accounted for with weights in gxa.
     826    329366064 :                    if ((choice==2.or.choice==23) .and. signs==1) then
     827      3319319 :                      ishift=0;if (choice==23) ishift=6
     828      3319319 :                      ia5=ia+ia3-1
     829     14224555 :                      do ii=1,ilang2
     830     10905236 :                        jj=ii-1+jjs
     831     46940263 :                        do mu=1,3
     832              : !                        (includes also factor of 2 from "2*Re[stuff]")
     833     32715708 :                          indx=mu+3*(ia5-1)+ishift
     834              :                          enlout(indx)=enlout(indx)+two*&
     835              : &                         ( gxafac(1,jj,ia,iproj)*dgxdt(1,mu,jj,ia,iproj,ispin)&
     836     43620944 : &                         +gxafac(2,jj,ia,iproj)*dgxdt(2,mu,jj,ia,iproj,ispin))
     837              :                        end do
     838              :                      end do
     839              :                    end if
     840              : 
     841              : !                  ----  Accumulate stress tensor contributions if requested.
     842    329366064 :                    if ((choice==3.or.choice==23).and.signs==1) then
     843              : !                    1- Compute contractions involving gxa and dgxds:
     844              : !                    --- Same formula for Scalar-relativistic and Spin-orbit ---
     845      2269630 :                      if (ilang==1) then
     846      4888702 :                        do ii=1,6
     847              :                          rank2(ii)=2.d0*&
     848              : &                         (gxafac(1,1,ia,iproj)*dgxds(1,ii,ia,iproj,isp)+ &
     849      4888702 : &                         gxafac(2,1,ia,iproj)*dgxds(2,ii,ia,iproj,isp) )
     850              :                        end do
     851      1571244 :                      else if (ilang==2) then
     852              :                        call cont13(gxafac(:,jjs:jjs+2,ia,iproj),&
     853       867129 : &                       dgxds(:, 7:16,ia,iproj,isp),rank2)
     854       704115 :                      else if (ilang==3) then
     855              :                        call cont24(gxafac(:,jjs:jjs+5,ia,iproj),&
     856       634069 : &                       dgxds(:,17:31,ia,iproj,isp),rank2)
     857        70046 :                      else if (ilang==4) then
     858              :                        call cont35(gxafac(:,jjs:jjs+9,ia,iproj),&
     859        70046 : &                       dgxds(:,32:52,ia,iproj,isp),rank2)
     860              :                      end if
     861              : !                    In all cases add rank2 term into stress tensor
     862     15887410 :                      strsnl(:)=strsnl(:)-rank2(:)
     863              : !                    2- Compute contractions involving gxa and gxa:
     864      2269630 :                      if(ispinor==1) then
     865              : !                      2a ------ Scalar-Relativistic ------
     866      1923722 :                        if (ilang==2) then
     867              :                          strsnl(1)=strsnl(1)-wt(ilang,iproj)*2.d0*&
     868              : &                         (gxa(1,jjs  ,ia,iproj,ispin)*gxa(1,jjs  ,ia,iproj,ispin)+&
     869       696849 : &                         gxa(2,jjs  ,ia,iproj,ispin)*gxa(2,jjs  ,ia,iproj,ispin))
     870              :                          strsnl(2)=strsnl(2)-wt(ilang,iproj)*2.d0*&
     871              : &                         (gxa(1,jjs+1,ia,iproj,ispin)*gxa(1,jjs+1,ia,iproj,ispin)+&
     872       696849 : &                         gxa(2,jjs+1,ia,iproj,ispin)*gxa(2,jjs+1,ia,iproj,ispin))
     873              :                          strsnl(3)=strsnl(3)-wt(ilang,iproj)*2.d0*&
     874              : &                         (gxa(1,jjs+2,ia,iproj,ispin)*gxa(1,jjs+2,ia,iproj,ispin)+&
     875       696849 : &                         gxa(2,jjs+2,ia,iproj,ispin)*gxa(2,jjs+2,ia,iproj,ispin))
     876              :                          strsnl(4)=strsnl(4)-wt(ilang,iproj)*2.d0*&
     877              : &                         (gxa(1,jjs+2,ia,iproj,ispin)*gxa(1,jjs+1,ia,iproj,ispin)+&
     878       696849 : &                         gxa(2,jjs+2,ia,iproj,ispin)*gxa(2,jjs+1,ia,iproj,ispin))
     879              :                          strsnl(5)=strsnl(5)-wt(ilang,iproj)*2.d0*&
     880              : &                         (gxa(1,jjs+2,ia,iproj,ispin)*gxa(1,jjs  ,ia,iproj,ispin)+&
     881       696849 : &                         gxa(2,jjs+2,ia,iproj,ispin)*gxa(2,jjs  ,ia,iproj,ispin))
     882              :                          strsnl(6)=strsnl(6)-wt(ilang,iproj)*2.d0*&
     883              : &                         (gxa(1,jjs+1,ia,iproj,ispin)*gxa(1,jjs  ,ia,iproj,ispin)+&
     884       696849 : &                         gxa(2,jjs+1,ia,iproj,ispin)*gxa(2,jjs  ,ia,iproj,ispin))
     885      1226873 :                        else if (ilang==3) then
     886       491121 :                          call trace2(gxa(:,jjs:jjs+5,ia,iproj,ispin),gmet,trace)
     887       491121 :                          call cont22(gxa(:,jjs:jjs+5,ia,iproj,ispin),gmet,rank2)
     888      3437847 :                          do ii=1,6
     889              :                            strsnl(ii)=strsnl(ii)+wt(ilang,iproj)*&
     890              : &                           (2.d0*(trace(1)*gxa(1,jjs+ii-1,ia,iproj,ispin)+&
     891      3437847 : &                           trace(2)*gxa(2,jjs+ii-1,ia,iproj,ispin))-3.d0*rank2(ii))
     892              :                          end do
     893       735752 :                        else if (ilang==4) then
     894        37366 :                          call cont3(gxa(:,jjs:jjs+9,ia,iproj,ispin),gmet,rank2)
     895       261562 :                          strsnl(:)=strsnl(:)-wt(ilang,iproj)*rank2(:)
     896              :                        end if
     897              :                      else
     898              : !                      2b ------ Spin-orbit ------
     899      1037724 :                        do ispinp=1,nspinortot
     900      1037724 :                          if (ilang==3) then
     901              :                            call cont22so(gxa(:,jjs:jjs+5,ia,iproj,ispin),&
     902              : &                           gxa(:,jjs:jjs+5,ia,iproj,ispinp),&
     903       285896 : &                           amet(:,:,:,ispin,ispinp),rank2)
     904      2001272 :                            strsnl(:)=strsnl(:)-wt(ilang,iproj)*3.d0*rank2(:)
     905       405920 :                          else if (ilang==4) then
     906              :                            call cont33so(gxa(:,jjs:jjs+9,ia,iproj,ispin),&
     907              : &                           gxa(:,jjs:jjs+9,ia,iproj,ispinp),&
     908        65360 : &                           gmet,amet(:,:,:,ispin,ispinp),rank2)
     909       457520 :                            strsnl(:)=strsnl(:)-wt(ilang,iproj)*rank2(:)
     910              :                          end if
     911              :                        end do
     912              :                      end if
     913              : !                    3- Compute contractions involving gxa and gxa due to
     914              : !                    gradients of antisymmetric tensor (amet):
     915              : !                    --- Only in case of Spin-orbit ---
     916      2269630 :                      if(ispinor==2) then
     917      1037724 :                        do ispinp=1,nspinortot
     918              : !                        Be carefull: no need to compute rank2c(:,1:3) !
     919       691816 :                          if (ilang==2) then
     920              :                            rank2c(1,4)=gxa(1,jjs+2,ia,iproj,ispin)*gxa(1,jjs+1,ia,iproj,ispinp)&
     921       340560 : &                           +gxa(2,jjs+2,ia,iproj,ispin)*gxa(2,jjs+1,ia,iproj,ispinp)
     922              :                            rank2c(2,4)=gxa(1,jjs+2,ia,iproj,ispin)*gxa(2,jjs+1,ia,iproj,ispinp)&
     923       340560 : &                           -gxa(2,jjs+2,ia,iproj,ispin)*gxa(1,jjs+1,ia,iproj,ispinp)
     924              :                            rank2c(1,5)=gxa(1,jjs+2,ia,iproj,ispin)*gxa(1,jjs  ,ia,iproj,ispinp)&
     925       340560 : &                           +gxa(2,jjs+2,ia,iproj,ispin)*gxa(2,jjs  ,ia,iproj,ispinp)
     926              :                            rank2c(2,5)=gxa(1,jjs+2,ia,iproj,ispin)*gxa(2,jjs  ,ia,iproj,ispinp)&
     927       340560 : &                           -gxa(2,jjs+2,ia,iproj,ispin)*gxa(1,jjs  ,ia,iproj,ispinp)
     928              :                            rank2c(1,6)=gxa(1,jjs+1,ia,iproj,ispin)*gxa(1,jjs  ,ia,iproj,ispinp)&
     929       340560 : &                           +gxa(2,jjs+1,ia,iproj,ispin)*gxa(2,jjs  ,ia,iproj,ispinp)
     930              :                            rank2c(2,6)=gxa(1,jjs+1,ia,iproj,ispin)*gxa(2,jjs  ,ia,iproj,ispinp)&
     931       340560 : &                           -gxa(2,jjs+1,ia,iproj,ispin)*gxa(1,jjs  ,ia,iproj,ispinp)
     932       351256 :                          else if (ilang==3) then
     933              :                            call cont22cso(gxa(:,jjs:jjs+5,ia,iproj,ispin),&
     934              : &                           gxa(:,jjs:jjs+5,ia,iproj,ispinp),&
     935       285896 : &                           gmet,rank2c)
     936        65360 :                          else if (ilang==4) then
     937              :                            call cont33cso(gxa(:,jjs:jjs+9,ia,iproj,ispin),&
     938              : &                           gxa(:,jjs:jjs+9,ia,iproj,ispinp),&
     939        65360 : &                           gmet,rank2c)
     940              :                          end if
     941      1037724 :                          if (ilang>1) then
     942      2767264 :                            do jj=1,3
     943      8993608 :                              do ii=4,6
     944              :                                strsso(ii,jj)=strsso(ii,jj)-2.d0*wt(ilang,iproj)*&
     945              : &                               (pauli(1,ispin,ispinp,jj)*rank2c(2,ii)+&
     946      8301792 : &                               pauli(2,ispin,ispinp,jj)*rank2c(1,ii))
     947              :                              end do
     948              :                            end do
     949              :                          end if
     950              :                        end do
     951              :                      end if
     952              : !                    Enf if (choice==3)
     953              :                    end if
     954              : 
     955              : !                  ----  Accumulate dynamical matrix contributions if requested.
     956    329366064 :                    if (choice==4) then
     957       976932 :                      ia5=ia+ia3-1
     958      4010446 :                      do ii=1,ilang2
     959      3033514 :                        jj=ii-1+jjs
     960     21234598 :                        do mu=1,6
     961              : !                        (includes also factor of 2 from "2*Re[stuff]")
     962              :                          enlout(mu+6*(ia5-1))=enlout(mu+6*(ia5-1))+two*&
     963              : &                         (gxafac(1,jj,ia,iproj)*dgxdt(1,mu+3,jj,ia,iproj,ispin)&
     964     21234598 : &                         +gxafac(2,jj,ia,iproj)*dgxdt(2,mu+3,jj,ia,iproj,ispin))
     965              :                        end do
     966     12134056 :                        do mu=1,3
     967              :                          enlout(mu+6*(ia5-1))=enlout(mu+6*(ia5-1))+two*&
     968              : &                         (dgxdtfac(1,mu,jj,ia,iproj)*dgxdt(1,mu,jj,ia,iproj,ispin)&
     969     12134056 : &                         +dgxdtfac(2,mu,jj,ia,iproj)*dgxdt(2,mu,jj,ia,iproj,ispin))
     970              :                        end do
     971              :                        enlout(4+6*(ia5-1))=enlout(4+6*(ia5-1)) +two*&
     972              : &                       (dgxdtfac(1,2,jj,ia,iproj)*dgxdt(1,3,jj,ia,iproj,ispin)&
     973      3033514 : &                       +dgxdtfac(2,2,jj,ia,iproj)*dgxdt(2,3,jj,ia,iproj,ispin))
     974              :                        enlout(5+6*(ia5-1))=enlout(5+6*(ia5-1)) +two*&
     975              : &                       (dgxdtfac(1,1,jj,ia,iproj)*dgxdt(1,3,jj,ia,iproj,ispin)&
     976      3033514 : &                       +dgxdtfac(2,1,jj,ia,iproj)*dgxdt(2,3,jj,ia,iproj,ispin))
     977              :                        enlout(6+6*(ia5-1))=enlout(6+6*(ia5-1)) +two*&
     978              : &                       (dgxdtfac(1,1,jj,ia,iproj)*dgxdt(1,2,jj,ia,iproj,ispin)&
     979      4010446 : &                       +dgxdtfac(2,1,jj,ia,iproj)*dgxdt(2,2,jj,ia,iproj,ispin))
     980              :                      end do
     981              :                    end if
     982              : 
     983              : !                  ----  Accumulate elastic tensor contributions if requested.
     984              : 
     985    506152007 :                    if(choice==6) then
     986              : !                    XG 081121 : msg to the person who has introduced this CPP option (sorry, I did not have to time to locate who did this ...)
     987              : !                    This section of ABINIT should be allowed by default to the user. I have found that on the contrary, the build
     988              : !                    system defaults are such that this section is forbidden by default. You might restore this flag if at the same time,
     989              : !                    you modify the build system in such a way that by default this section is included, and if the user wants, it can disable it.
     990              : !                    #if defined USE_NLSTRAIN_LEGENDRE
     991       164504 :                      ia5=ia+ia3-1
     992       164504 :                      jjs1=((ilang)*(ilang+1)*(ilang+2))/6
     993       164504 :                      jjs2=-3+((ilang+1)*(ilang+2)*(ilang+3))/6
     994       164504 :                      jjs3=-9+((ilang+2)*(ilang+3)*(ilang+4))/6
     995       164504 :                      jjs4=-19+((ilang+3)*(ilang+4)*(ilang+5))/6
     996              : 
     997              : !                    Contribution for two diagonal strains (basically, the nonlocal
     998              : !                    enlk)
     999              :                      temp(:,1:((rank+1)*(rank+2))/2)= &
    1000      1781360 : &                     gxa(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj,ispin)
    1001       164504 :                      call metcon(rank,gmet,temp,tmpfac)
    1002       164504 :                      e2nldd=zero
    1003       703456 :                      do ii=1,((rank+1)*(rank+2))/2
    1004              :                        e2nldd=e2nldd+&
    1005              : &                       (gxa(1,jjs-1+ii,ia,iproj,ispin)*tmpfac(1,ii)+&
    1006       703456 : &                       gxa(2,jjs-1+ii,ia,iproj,ispin)*tmpfac(2,ii))
    1007              :                      end do
    1008              : 
    1009              : !                    Terms involving one ucvol derivative (diagonal strain only)
    1010              : !                    and one derivative of nonlocal operator
    1011              : !                    Loop over strain index
    1012      1151528 :                      do istr2=1,6
    1013              : 
    1014              : !                      rank->rank+2
    1015       987024 :                        iterm=1
    1016              :                        temp(:,1:((rank+1)*(rank+2))/2)= &
    1017     10688160 : &                       gxa(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj,ispin)
    1018       987024 :                        call metstr(istr2,rank,iterm,gmet,gprimd,temp,tmpfac)
    1019       987024 :                        e2nl_tmp(istr2)=0.d0
    1020     11084976 :                        do ii=1,((rank+3)*(rank+4))/2
    1021              :                          e2nl_tmp(istr2)=e2nl_tmp(istr2)-2.d0*&
    1022              : &                         (dgxds(1,jjs2-1+ii,ia,iproj,isp)*tmpfac(1,ii)+&
    1023     11084976 : &                         dgxds(2,jjs2-1+ii,ia,iproj,isp)*tmpfac(2,ii))
    1024              :                        end do
    1025              : !                      rank->rank
    1026              : 
    1027       987024 :                        iterm=2
    1028              :                        temp(:,1:((rank+1)*(rank+2))/2)= &
    1029     10688160 : &                       gxa(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj,ispin)
    1030       987024 :                        call metstr(istr2,rank,iterm,gmet,gprimd,temp,tmpfac)
    1031      4385240 :                        do ii=1,((rank+1)*(rank+2))/2
    1032              :                          e2nl_tmp(istr2)=e2nl_tmp(istr2)-&
    1033              : &                         (gxa(1,jjs-1+ii,ia,iproj,ispin)*tmpfac(1,ii)+&
    1034      4220736 : &                         gxa(2,jjs-1+ii,ia,iproj,ispin)*tmpfac(2,ii))
    1035              :                        end do
    1036              : !                      DEBUG
    1037              : !                      This and subsequent similar debug sections evaluate the
    1038              : !                      hermitial conjugate of the contraction immeditely above
    1039              : !                      and the comparison was useful for development purposes.
    1040              : !                      rank+2->rank
    1041              : !                      iterm=3
    1042              : !                      temp(:,1:((rank+3)*(rank+4))/2)= &
    1043              : !                      dgxds(:,jjs2:jjs2-1+((rank+3)*(rank+4))/2,ia,iproj,ispin)
    1044              : !                      call metstr(istr2,rank,iterm,gmet,gprimd,temp,tmpfac)
    1045              : !                      e2nl_tmp(istr2)=0.d0
    1046              : !                      do ii=1,((rank+1)*(rank+2))/2
    1047              : !                      e2nl_tmp(istr2)=e2nl_tmp(istr2)-&
    1048              : !                      &             (gxa(1,jjs-1+ii,ia,iproj,ispin)*tmpfac(1,ii)+&
    1049              : !                      &              gxa(2,jjs-1+ii,ia,iproj,ispin)*tmpfac(2,ii))
    1050              : !                      end do
    1051              : !                      ENDDEBUG
    1052              :                      end do
    1053              : 
    1054              : !                    Terms involving two derivatives of the nonlocal operator
    1055              : !                    Loop over 2nd strain index
    1056      1151528 :                      do istr2=1,6
    1057              : !                      Loop over 1st strain index, upper triangle only
    1058      6909168 :                        do istr1=1,6
    1059      5922144 :                          iest=istr1+(3*natom+6)*(istr2-1)
    1060              : 
    1061              : !                        Accumulate terms corresponding to two derivatives of ucvol
    1062              : !                        (simply the nonlocal energy contributin) for both indices
    1063              : !                        corresponding to diagonal strains
    1064              : 
    1065      5922144 :                          if(istr1<=3 .and. istr2<=3) then
    1066      1480536 :                            enlout(iest)= enlout(iest)+wt(ilang,iproj)*e2nldd
    1067              :                          end if
    1068              : 
    1069              : !                        Accumulate terms computed above from 1st derivatives
    1070              : !                        when one or more indices corresponds to diagonal strain
    1071      5922144 :                          if(istr2<=3) then
    1072      2961072 :                            enlout(iest)= enlout(iest)+wt(ilang,iproj)*e2nl_tmp(istr1)
    1073              :                          end if
    1074      5922144 :                          if(istr1<=3) then
    1075      2961072 :                            enlout(iest)= enlout(iest)+wt(ilang,iproj)*e2nl_tmp(istr2)
    1076              :                          end if
    1077              : 
    1078              : !                        rank->rank+4
    1079              :                          call contstr21(istr2,istr1,rank,gmet,gprimd,e2nl,&
    1080              : &                         gxa(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj,ispin),&
    1081      5922144 : &                         d2gxds2(:,jjs4:jjs4-1+((rank+5)*(rank+6))/2,ia,iproj,isp))
    1082      5922144 :                          enlout(iest)= enlout(iest)+wt(ilang,iproj)*e2nl
    1083              : 
    1084              : !                        DEBUG
    1085              : !                        rank+4->rank
    1086              : !                        call contstr22(istr2,istr1,rank,gmet,gprimd,e2nl,&
    1087              : !                        &             d2gxds2(:,jjs4:jjs4-1+((rank+5)*(rank+6))/2,ia,iproj,ispin),&
    1088              : !                        &             gxa(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj,ispin))
    1089              : !                        enlout(iest)= enlout(iest)+wt(ilang,iproj)*e2nl
    1090              : !                        ENDDEBUG
    1091              : 
    1092              : !                        rank->rank+2
    1093              :                          call contstr23(istr2,istr1,rank,gmet,gprimd,e2nl,&
    1094              : &                         gxa(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj,ispin),&
    1095      5922144 : &                         dgxds(:,jjs2:jjs2-1+((rank+3)*(rank+4))/2,ia,iproj,isp))
    1096      5922144 :                          enlout(iest)= enlout(iest)+wt(ilang,iproj)*e2nl
    1097              : !                        DEBUG
    1098              : 
    1099              : !                        rank+2->rank
    1100              : !                        call contstr24(istr2,istr1,rank,gmet,gprimd,e2nl,&
    1101              : !                        &             dgxds(:,jjs2:jjs2-1+((rank+3)*(rank+4))/2,ia,iproj,ispin),&
    1102              : !                        &             gxa(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj,ispin))
    1103              : !                        enlout(iest)= enlout(iest)+wt(ilang,iproj)*e2nl
    1104              : !                        ENDDEBUG
    1105              : 
    1106              : !                        rank+2->rank+2
    1107      5922144 :                          if(rank<=2) then
    1108              :                            call contstr25(istr2,istr1,rank,gmet,gprimd,e2nl,&
    1109              : &                           dgxds(:,jjs2:jjs2-1+((rank+3)*(rank+4))/2,ia,iproj,isp),&
    1110      5921568 : &                           dgxds(:,jjs2:jjs2-1+((rank+3)*(rank+4))/2,ia,iproj,isp))
    1111              :                          else
    1112              :                            call contstr25a(istr2,istr1,rank,gmet,gprimd,e2nl,&
    1113              : &                           dgxds(:,jjs2:jjs2-1+((rank+3)*(rank+4))/2,ia,iproj,isp),&
    1114          576 : &                           dgxds(:,jjs2:jjs2-1+((rank+3)*(rank+4))/2,ia,iproj,isp))
    1115              :                          end if
    1116      5922144 :                          enlout(iest)= enlout(iest)+wt(ilang,iproj)*e2nl
    1117              : 
    1118              : !                        rank->rank
    1119              :                          call contstr26(istr2,istr1,rank,gmet,gprimd,e2nl,&
    1120              : &                         gxa(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj,ispin),&
    1121      5922144 : &                         gxa(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj,ispin))
    1122      6909168 :                          enlout(iest)= enlout(iest)+wt(ilang,iproj)*e2nl
    1123              : 
    1124              :                        end do !istr1
    1125              : 
    1126              : !                      Contributions to internal strain (one cartesian strain and one
    1127              : !                      reduced-coordinate atomic displacement derivative).
    1128       987024 :                        iest=7+3*(ia5-1)+(3*natom+6)*(istr2-1)
    1129              : 
    1130              : !                      rank->rank+3
    1131              :                        call contistr03(istr2,rank,gmet,gprimd,eisnl,&
    1132              : &                       gxa(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj,ispin),&
    1133       987024 : &                       d2gxdis(:,jjs3:jjs3-1+((rank+4)*(rank+5))/2,ia,iproj,isp))
    1134              :                        enlout(iest:iest+2)= enlout(iest:iest+2)&
    1135      3948096 : &                       +wt(ilang,iproj)*eisnl(1:3)
    1136              : 
    1137              : !                      DEBUG
    1138              : !                      rank+3->rank
    1139              : !                      call contistr30(istr2,rank,gmet,gprimd,eisnl,&
    1140              : !                      &            d2gxdis(:,jjs3:jjs3-1+((rank+4)*(rank+5))/2,ia,iproj,ispin),&
    1141              : !                      &            gxa(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj,ispin))
    1142              : !                      enlout(iest:iest+2)= enlout(iest:iest+2)&
    1143              : !                      &            +wt(ilang,iproj)*eisnl(1:3)
    1144              : !                      ENDDEBUG
    1145              : 
    1146              : !                      rank+1->rank+2
    1147              :                        call contistr12(istr2,rank,gmet,gprimd,eisnl,&
    1148              : &                       dgxdis(:,jjs1:jjs1-1+((rank+2)*(rank+3))/2,ia,iproj,isp),&
    1149       987024 : &                       dgxds(:,jjs2:jjs2-1+((rank+3)*(rank+4))/2,ia,iproj,isp))
    1150              :                        enlout(iest:iest+2)= enlout(iest:iest+2)&
    1151      3948096 : &                       +wt(ilang,iproj)*eisnl(1:3)
    1152              : 
    1153              : !                      DEBUG
    1154              : !                      rank+2->rank+1
    1155              : !                      call contistr21(istr2,rank,gmet,gprimd,eisnl,&
    1156              : !                      &            dgxds(:,jjs2:jjs2-1+((rank+3)*(rank+4))/2,ia,iproj,ispin),&
    1157              : !                      &            dgxdis(:,jjs1:jjs1-1+((rank+2)*(rank+3))/2,ia,iproj,ispin))
    1158              : !                      enlout(iest:iest+2)= enlout(iest:iest+2)&
    1159              : !                      &            +wt(ilang,iproj)*eisnl(1:3)
    1160              : !                      ENDDEBUG
    1161              : 
    1162              : !                      rank->rank+1
    1163              :                        call contistr01(istr2,rank,gmet,gprimd,eisnl,&
    1164              : &                       gxa(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj,ispin),&
    1165       987024 : &                       dgxdis(:,jjs1:jjs1-1+((rank+2)*(rank+3))/2,ia,iproj,isp))
    1166              :                        enlout(iest:iest+2)= enlout(iest:iest+2)&
    1167      4112600 : &                       +wt(ilang,iproj)*eisnl(1:3)
    1168              : !
    1169              : !                      DEBUG
    1170              : !                      rank+1->rank
    1171              : !                      call contistr10(istr2,rank,gmet,gprimd,eisnl,&
    1172              : !                      &            dgxdis(:,jjs1:jjs1-1+((rank+2)*(rank+3))/2,ia,iproj,ispin),&
    1173              : !                      &            gxa(:,jjs:jjs-1+((rank+1)*(rank+2))/2,ia,iproj,ispin))
    1174              : !                      enlout(iest:iest+2)= enlout(iest:iest+2)&
    1175              : !                      &            +wt(ilang,iproj)*eisnl(1:3)
    1176              : !                      ENDDEBUG
    1177              : 
    1178              :                      end do !istr2
    1179              :                    end if !choice==6
    1180              : 
    1181              : !                  End loop over iproj:
    1182              :                  end do
    1183              : !                End condition of existence of a reference state:
    1184              :                end if
    1185              : 
    1186              : !              End loop over ilang:
    1187              :              end do
    1188              : 
    1189              : !            End loop over ia:
    1190              :            end do
    1191              : 
    1192              : !          Operate with the non-local potential on the projected scalars,
    1193              : !          in order to get matrix element [NOT needed if only force or stress
    1194              : !          or dynamical matrix is being computed].
    1195              : 
    1196     92031921 :            if (signs==2) then
    1197     47778907 :              if(nloalg(2)<=0 .and. choice==2)then
    1198              : !              Prepare the phase k+q factors for the atoms between ia3 and ia4:
    1199              : !              they were not prepared previously for nloalg(2)<=0 and choice==2.
    1200              :                call ph1d3d(ia3,ia4,kgout,matblk,natom,npwout,&
    1201      2835862 : &               n1,n2,n3,phkxredout,ph1d,ph3dout)
    1202              :              end if
    1203              : 
    1204              : !            call timab(74+choice,1,tsec)
    1205     47778907 :              sign=-1
    1206              : !            The duplication of the opernl calls has the purpose to avoid
    1207              : !            copying vectout/vectout_s
    1208     47778907 :              if(ispin==1.or.nspinor==1)then
    1209     42915664 :                if( nloalg(1)==2) then
    1210              :                  call opernl2(choice,dgxdis,dgxdsfac,d2gxdis,d2gxds2,dgxdtfac,&
    1211              : &                 ffnlout,gmet,gxafac,ia3,idir,indlmn_s,ispinor,istwf_k,itypat,&
    1212              : &                 jproj,kgout,kpgout,kptout,lmnmax,matblk,mincat,mlang1,mlang3,mlang4,&
    1213              : &                 mlang5,mlang6,mproj,ndgxdt,dimffnlout,nincat,nkpgout,nlang,nloalg,npwout,&
    1214        10394 : &                 ntypat,ph3dout,sign,vectout)
    1215     42905270 :                else if( nloalg(1)==3) then
    1216              :                  call opernl3(choice,dgxdis,dgxdsfac,d2gxdis,d2gxds2,dgxdtfac,&
    1217              : &                 ffnlout,gmet,gxafac,ia3,idir,indlmn_s,ispinor,istwf_k,itypat,&
    1218              : &                 jproj,kgout,kpgout,kptout,lmnmax,matblk,mincat,mlang1,mlang3,mlang4,&
    1219              : &                 mlang5,mlang6,mproj,ndgxdt,dimffnlout,nincat,nkpgout,nlang,nloalg,npwout,&
    1220       125702 : &                 ntypat,ph3dout,sign,vectout)
    1221     42779568 :                else if( nloalg(1)==4) then
    1222              :                  call opernl4b(choice,dgxdsfac,dgxdtfac,ffnlout,gmet,gxafac,&
    1223              : &                 ia3,idir,indlmn_s,ispinor,itypat,jproj,kgout,kpgout,kptout,&
    1224              : &                 lmnmax,matblk,mincat,mlang3,mlang4,mproj,ndgxdt,&
    1225     42779568 : &                 dimffnlout,nincat,nkpgout,nlang,nloalg,npwout,ntypat,ph3dout,vectout)
    1226              :                end if
    1227              :              else  ! if ispin == 2
    1228   2752832490 :                vectout_s(:,:)=zero
    1229      4863243 :                if( nloalg(1)==2) then
    1230              :                  call opernl2(choice,dgxdis,dgxdsfac,d2gxdis,d2gxds2,dgxdtfac,&
    1231              : &                 ffnlout,gmet,gxafac,ia3,idir,indlmn_s,ispinor,istwf_k,itypat,&
    1232              : &                 jproj,kgout,kpgout,kptout,lmnmax,matblk,mincat,mlang1,mlang3,mlang4,&
    1233              : &                 mlang5,mlang6,mproj,ndgxdt,dimffnlout,nincat,nkpgout,nlang,nloalg,npwout,&
    1234            0 : &                 ntypat,ph3dout,sign,vectout_s)
    1235      4863243 :                else if( nloalg(1)==3) then
    1236              :                  call opernl3(choice,dgxdis,dgxdsfac,d2gxdis,d2gxds2,dgxdtfac,&
    1237              : &                 ffnlout,gmet,gxafac,ia3,idir,indlmn_s,ispinor,istwf_k,itypat,&
    1238              : &                 jproj,kgout,kpgout,kptout,lmnmax,matblk,mincat,mlang1,mlang3,mlang4,&
    1239              : &                 mlang5,mlang6,mproj,ndgxdt,dimffnlout,nincat,nkpgout,nlang,nloalg,npwout,&
    1240            0 : &                 ntypat,ph3dout,sign,vectout_s)
    1241      4863243 :                else if( nloalg(1)==4) then
    1242              :                  call opernl4b(choice,dgxds,dgxdtfac,ffnlout,gmet,gxafac,&
    1243              : &                 ia3,idir,indlmn_s,ispinor,itypat,jproj,kgout,kpgout,kptout,&
    1244              : &                 lmnmax,matblk,mincat,mlang3,mlang4,mproj,ndgxdt,&
    1245      4863243 : &                 dimffnlout,nincat,nkpgout,nlang,nloalg,npwout,ntypat,ph3dout,vectout_s)
    1246              :                end if
    1247              :                vectout(1,1+npwout:2*npwout)=&
    1248    920852992 : &               vectout(1,1+npwout:2*npwout)+vectout_s(1,1:npwout)
    1249              :                vectout(2,1+npwout:2*npwout)=&
    1250    920852992 : &               vectout(2,1+npwout:2*npwout)+vectout_s(2,1:npwout)
    1251              : 
    1252              :              end if ! end ispin if
    1253              :            end if ! end signs==2 if
    1254              : 
    1255              : !          End loops over spins:
    1256              :          end do
    1257              : 
    1258              : !        End condition of existence of a non-local part for that type of atom:
    1259              :        end if
    1260              : 
    1261              : !      End loop over ispinor:
    1262              :      end do
    1263              : 
    1264              : !    End sum on atom subset loop, over ia3:
    1265              :    end do
    1266              : 
    1267              : !  End atom type loop, over itypat:
    1268     71836647 :    ia1=ia2+1
    1269              :  end do
    1270              : 
    1271              : !De-allocate temporary space.
    1272     29457648 :  ABI_FREE(ekb_s)
    1273     29457648 :  ABI_FREE(gxa)
    1274     29457648 :  ABI_FREE(gxafac)
    1275     29457648 :  ABI_FREE(dgxds)
    1276     29457648 :  ABI_FREE(dgxdt)
    1277     29457648 :  ABI_FREE(dgxdtfac)
    1278     29457648 :  ABI_FREE(wt)
    1279     29457648 :  ABI_FREE(jproj)
    1280     29457648 :  ABI_FREE(temp)
    1281     29457648 :  ABI_FREE(tmpfac)
    1282     29457648 :  ABI_FREE(dgxdsfac)
    1283     29457648 :  ABI_FREE(indlmn_s)
    1284              :  !if(choice==6)  then
    1285     29457648 :  ABI_FREE(dgxdis)
    1286     29457648 :  ABI_FREE(d2gxdis)
    1287     29457648 :  ABI_FREE(d2gxds2)
    1288              :  !end if
    1289              :  !if(nspinor==2) then
    1290     29457648 :  ABI_FREE(dgxds_s)
    1291     29457648 :  ABI_FREE(dgxdt_s)
    1292     29457648 :  ABI_FREE(gxa_s)
    1293              :  !end if
    1294              :  !if(nspinor==2.and.choice==6) then
    1295     29457648 :  ABI_FREE(dgxdis_s)
    1296     29457648 :  ABI_FREE(d2gxdis_s)
    1297     29457648 :  ABI_FREE(d2gxds2_s)
    1298              :  !end if
    1299     29457648 :  if (mpssoang>mpsang)  then
    1300      2339994 :    ABI_FREE(pauli)
    1301              :  end if
    1302              : 
    1303              : !Restore the original content of the vectin array.
    1304              : !Note that only the first part was modified
    1305     29457648 :  if(istwf_k/=1) then
    1306       904765 :    call scalewf_nonlop(istwf_k,mpi_enreg,npwin,2,vectin)
    1307              :  end if
    1308              : 
    1309     29457648 :  if (nspinor==2)  then
    1310      1552174 :    ABI_FREE(vectin_s)
    1311      1552174 :    ABI_FREE(vectout_s)
    1312              :  end if
    1313              : 
    1314     29457648 :  if (mpi_enreg%paral_spinor==1) then
    1315         4928 :    if (size(enlout)>0) call xmpi_sum(enlout,mpi_enreg%comm_spinor,ierr)
    1316         4928 :    call xmpi_sum(strsnl,mpi_enreg%comm_spinor,ierr)
    1317         4928 :    call xmpi_sum(enlk,mpi_enreg%comm_spinor,ierr)
    1318         4928 :    call xmpi_sum(strsso,mpi_enreg%comm_spinor,ierr)
    1319              :  end if
    1320              : 
    1321              : !Save non-local energy
    1322     29457648 :  if((choice==1).and.size(enlout)>0) enlout(1)=enlk ! on test v4/93 size(enlout) can be zero (PMA)
    1323              : 
    1324              : !Do final manipulations to produce strain gradients for
    1325              : !stress tensor, in cartesian coordinates
    1326     29564436 :  if ((choice==3.or.choice==23) .and. signs==1) then
    1327              : !  Convert strsnl from reduced to cartesian coordinates
    1328       106788 :    strsnl_out(:)=0.d0
    1329       106788 :    call strconv(strsnl,gprimd,strsnl_out)
    1330       106788 :    strsnl(:) = strsnl_out(:)
    1331              : !  Add diagonal part (fill up first 6 components of enlout with
    1332              : !  these gradients; elements 7,8,9 of enlout are not used)
    1333       106788 :    enlout(1)=strsnl(1)-enlk
    1334       106788 :    enlout(2)=strsnl(2)-enlk
    1335       106788 :    enlout(3)=strsnl(3)-enlk
    1336       106788 :    enlout(4)=strsnl(4)
    1337       106788 :    enlout(5)=strsnl(5)
    1338       106788 :    enlout(6)=strsnl(6)
    1339              : !  Eventually, add spin-orbit part due to gradients of
    1340              : !  antisymmetric tensor
    1341       106788 :    if (mpssoang>mpsang) then
    1342        17537 :      call strsocv(strsso,gprimd,strssoc)
    1343       122759 :      enlout(1:6)=enlout(1:6)+strssoc(:)
    1344              :    end if
    1345              :  end if
    1346              : 
    1347              : !DEBUG
    1348              : !write(std_out,*)' nonlop_pl: exit '
    1349              : !ENDDEBUG
    1350              : 
    1351              : contains
    1352              : !!***
    1353              : 
    1354              : !!****f* ABINIT/trace2
    1355              : !! NAME
    1356              : !! trace2
    1357              : !!
    1358              : !! FUNCTION
    1359              : !! Sum indices to compute trace of rank 2 tensor gxa related to l=2
    1360              : !! $trace=sum_{i,j} {gxa(i,j) gmet(i,j)}$
    1361              : !!
    1362              : !! INPUTS
    1363              : !!  gxa(2,6) = $sum_{G} {e^(2 \pi i G cdot t} {{f_2(|k+G|)} \over {|k+G|^2}} (k+G) cdot (k+G) C(G_{nk})}$
    1364              : !!  gmet(3,3)=(symmetric) metric tensor in reciprocal space (bohr^-2)
    1365              : !!
    1366              : !! OUTPUT
    1367              : !!  trace(2)=sum_{i,j} {gxa(i,j) gmet(i,j)}$ (Re and Im).
    1368              : !!
    1369              : !! NOTES
    1370              : !! Here index 6 refers to vector components
    1371              : !! of (k+G) but note tensor is symmetric=>only 6 components.
    1372              : !! The components are given in the order 11 22 33 32 31 21.
    1373              : !! The initial 2 handles the Re and Im parts.
    1374              : !!
    1375              : !! PARENTS
    1376              : !!      m_nonlop_pl
    1377              : !!
    1378              : !! CHILDREN
    1379              : !!
    1380              : !! SOURCE
    1381              : 
    1382       491121 : subroutine trace2(gxa,gmet,trace)
    1383              : 
    1384              : !Arguments ------------------------------------
    1385              : !arrays
    1386              :  real(dp),intent(in) :: gmet(3,3),gxa(2,6)
    1387              :  real(dp),intent(out) :: trace(2)
    1388              : 
    1389              : !Local variables-------------------------------
    1390              : !scalars
    1391              :  integer :: reim
    1392              : 
    1393              : ! *************************************************************************
    1394              : 
    1395              : !Write out index summation, Re and Im parts
    1396      1473363 :  do reim=1,2
    1397              :    trace(reim)=gxa(reim,1)*gmet(1,1)+gxa(reim,2)*gmet(2,2)+&
    1398              : &   gxa(reim,3)*gmet(3,3)+&
    1399              : &   2.0d0*(gxa(reim,4)*gmet(3,2)+gxa(reim,5)*gmet(3,1)+&
    1400      1473363 : &   gxa(reim,6)*gmet(2,1))
    1401              :  end do
    1402              : 
    1403       491121 : end subroutine trace2
    1404              : !!***
    1405              : 
    1406              : !!****f* ABINIT/strsocv
    1407              : !! NAME
    1408              : !! strsocv
    1409              : !!
    1410              : !! FUNCTION
    1411              : !! Convert from antisymmetric storage mode 3x3x3 rank3 tensor in reduced
    1412              : !! coordinates "red" to symmetric storage mode 3x3 rank2 tensor in
    1413              : !! cartesian coordinates "cart", using metric tensor "gprimd".
    1414              : !!
    1415              : !! INPUTS
    1416              : !!  red(6,3)=3x3x3 tensor in antisymmetric storage mode,
    1417              : !!           reduced coordinates
    1418              : !!  gprimd(3,3)=reciprocal space dimensional primitive translations
    1419              : !!
    1420              : !! OUTPUT
    1421              : !!  cart(6)=3x3 tensor in symmetric storage mode,
    1422              : !!          cartesian coordinates
    1423              : !!
    1424              : !! NOTES
    1425              : !! This routine is used to compute spin-orbit stress tensor.
    1426              : !!
    1427              : !! red is antisymmetric in first two indices and stored
    1428              : !!     as 11 22 33 32 31 21.
    1429              : !! cart is symmetric and stored as 11 22 33 32 31 21.
    1430              : !!
    1431              : !!{{\ \begin{eqnarray}
    1432              : !! cart(1,1) & = &        & red(i,j,2) G(3,i) G(1,j) + red(i,j,3) G(1,i) G(2,j) \nonumber
    1433              : !! cart(2,2) & = &        & red(i,j,1) G(2,i) G(3,j) + red(i,j,3) G(1,i) G(2,j) \nonumber
    1434              : !! cart(3,3) & = &        & red(i,j,1) G(2,i) G(3,j) + red(i,j,2) G(3,i) G(1,j) \nonumber
    1435              : !! cart(3,2) & = &  0.5 ( & red(i,j,3) G(1,i) G(3,j) + red(i,j,2) G(2,i) G(1,j)) \nonumber
    1436              : !! cart(3,1) & = &  0.5 ( & red(i,j,3) G(3,i) G(2,j) + red(i,j,1) G(2,i) G(1,j)) \nonumber
    1437              : !! cart(2,1) & = &  0.5 ( & red(i,j,2) G(3,i) G(2,j) + red(i,j,1) G(1,i) G(3,j))
    1438              : !! \end{eqnarray} }}
    1439              : !!
    1440              : !! PARENTS
    1441              : !!      m_nonlop_pl
    1442              : !!
    1443              : !! CHILDREN
    1444              : !!
    1445              : !! SOURCE
    1446              : 
    1447        17537 : subroutine strsocv(red,gprimd,cart)
    1448              : 
    1449              : !Arguments ------------------------------------
    1450              : !arrays
    1451              :  real(dp),intent(in) :: gprimd(3,3),red(6,3)
    1452              :  real(dp),intent(out) :: cart(6)
    1453              : 
    1454              : !Local variables-------------------------------
    1455              : !scalars
    1456              :  integer :: ii,jj
    1457              : !arrays
    1458              :  real(dp) :: work(3,3,3)
    1459              : 
    1460              : ! *************************************************************************
    1461              : 
    1462        70148 :  do ii=1,3
    1463        52611 :    work(1,1,ii)=0.d0
    1464        52611 :    work(2,2,ii)=0.d0
    1465        52611 :    work(3,3,ii)=0.d0
    1466        52611 :    work(3,2,ii)=red(4,ii) ; work(2,3,ii)=-red(4,ii)
    1467        52611 :    work(3,1,ii)=red(5,ii) ; work(1,3,ii)=-red(5,ii)
    1468        70148 :    work(2,1,ii)=red(6,ii) ; work(1,2,ii)=-red(6,ii)
    1469              :  end do
    1470              : 
    1471        17537 :  cart(:)=0.d0
    1472        70148 :  do jj=1,3
    1473       227981 :    do ii=1,3
    1474              :      cart(1)=cart(1)+work(ii,jj,2)*gprimd(3,ii)*gprimd(1,jj)&
    1475       157833 : &     +work(ii,jj,3)*gprimd(1,ii)*gprimd(2,jj)
    1476              :      cart(2)=cart(2)+work(ii,jj,1)*gprimd(2,ii)*gprimd(3,jj)&
    1477       157833 : &     +work(ii,jj,3)*gprimd(1,ii)*gprimd(2,jj)
    1478              :      cart(3)=cart(3)+work(ii,jj,1)*gprimd(2,ii)*gprimd(3,jj)&
    1479       157833 : &     +work(ii,jj,2)*gprimd(3,ii)*gprimd(1,jj)
    1480              :      cart(4)=cart(4)+work(ii,jj,3)*gprimd(1,ii)*gprimd(3,jj)&
    1481       157833 : &     +work(ii,jj,2)*gprimd(2,ii)*gprimd(1,jj)
    1482              :      cart(5)=cart(5)+work(ii,jj,3)*gprimd(3,ii)*gprimd(2,jj)&
    1483       157833 : &     +work(ii,jj,1)*gprimd(2,ii)*gprimd(1,jj)
    1484              :      cart(6)=cart(6)+work(ii,jj,2)*gprimd(3,ii)*gprimd(2,jj)&
    1485       210444 : &     +work(ii,jj,1)*gprimd(1,ii)*gprimd(3,jj)
    1486              :    end do
    1487              :  end do
    1488        17537 :  cart(4)=0.5d0*cart(4)
    1489        17537 :  cart(5)=0.5d0*cart(5)
    1490        17537 :  cart(6)=0.5d0*cart(6)
    1491              : 
    1492        17537 : end subroutine strsocv
    1493              : !!***
    1494              : 
    1495              : !!****f* ABINIT/scalewf_nonlop
    1496              : !! NAME
    1497              : !! scalewf_nonlop
    1498              : !!
    1499              : !! FUNCTION
    1500              : !! At the start of nonlop (or similar routines), as well as its end,
    1501              : !! the wavefunctions, when stored with istwfk/=2,
    1502              : !! need to be scaled (by a factor of 2 or 1/2),
    1503              : !! except for the G=0 component.
    1504              : !! Only the first spinor component is to be modified.
    1505              : !!
    1506              : !! INPUTS
    1507              : !!  istwf_k=storage mode of the vector
    1508              : !!  mpi_enreg=information about MPI parallelization
    1509              : !!  npw=number of planewaves
    1510              : !!  option=1 multiply by 2
    1511              : !!        =2 multiply by 1/2
    1512              : !!
    1513              : !! OUTPUT
    1514              : !!  (see side effects)
    1515              : !!
    1516              : !! SIDE EFFECTS
    1517              : !!  vect(2,npw)=vector that is rescaled
    1518              : !!
    1519              : !! NOTES
    1520              : !!  XG030513 : MPIWF One should pay attention to the
    1521              : !!  G=0 component, that will be only one one proc...
    1522              : !!
    1523              : !! PARENTS
    1524              : !!      m_nonlop_pl
    1525              : !!
    1526              : !! CHILDREN
    1527              : !!
    1528              : !! SOURCE
    1529              : 
    1530      1809530 : subroutine scalewf_nonlop(istwf_k,mpi_enreg,npw,option,vect)
    1531              : 
    1532              : !Arguments ------------------------------------
    1533              : !This type is defined in defs_mpi
    1534              : !scalars
    1535              :  integer,intent(in) :: istwf_k,npw,option
    1536              :  type(MPI_type),intent(in) :: mpi_enreg
    1537              : !arrays
    1538              :  real(dp),intent(inout) :: vect(2,npw)
    1539              : 
    1540              : !Local variables-------------------------------
    1541              : !scalars
    1542              :  integer :: ipw
    1543              :  real(dp) :: scale
    1544              :  character(len=500) :: msg
    1545              : 
    1546              : ! *************************************************************************
    1547              : 
    1548              :  DBG_ENTER("COLL")
    1549              : 
    1550      1809530 :  if(istwf_k/=1)then
    1551              : 
    1552      1809530 :    if(option/=1 .and. option/=2)then
    1553              :      write(msg,'(a,a,a,i0)')&
    1554            0 :      'The argument option should be 1 or 2,',ch10,&
    1555            0 :      'however, option=',option
    1556            0 :      ABI_BUG(msg)
    1557              :    end if
    1558              : 
    1559      1809530 :    scale=two
    1560      1809530 :    if(option==2)scale=half
    1561              : 
    1562              : !  Storage for the Gamma point. The component of the G=0 vector
    1563              : !  should not be scaled, and no G=0 imaginary part is allowed.
    1564      1809530 :    if(istwf_k==2)then
    1565       993540 :      if (mpi_enreg%me_g0_fft==1) then
    1566       991160 :        vect(2,1)=zero
    1567              : !$OMP PARALLEL DO
    1568    632878994 :        do ipw=2,npw
    1569    631887834 :          vect(1,ipw)=scale*vect(1,ipw)
    1570    632878994 :          vect(2,ipw)=scale*vect(2,ipw)
    1571              :        end do
    1572              : !$OMP END PARALLEL DO
    1573              :      else
    1574              : !$OMP PARALLEL DO
    1575       247520 :        do ipw=1,npw
    1576       245140 :          vect(1,ipw)=scale*vect(1,ipw)
    1577       247520 :          vect(2,ipw)=scale*vect(2,ipw)
    1578              :        end do
    1579              : !$OMP END PARALLEL DO
    1580              :      end if
    1581              :    end if
    1582              : 
    1583              : !  Other storage modes, for k points with time-reversal symmetry.
    1584              : !  All components should be scaled.
    1585      1809530 :    if(istwf_k>2)then
    1586              : !$OMP PARALLEL DO
    1587    262493056 :      do ipw=1,npw
    1588    261677066 :        vect(1,ipw)=scale*vect(1,ipw)
    1589    262493056 :        vect(2,ipw)=scale*vect(2,ipw)
    1590              :      end do
    1591              : !$OMP END PARALLEL DO
    1592              :    end if
    1593              : 
    1594              :  end if ! istwf_k/=1
    1595              : 
    1596              :  DBG_EXIT("COLL")
    1597              : 
    1598      1809530 : end subroutine scalewf_nonlop
    1599              : !!***
    1600              : 
    1601              : !!****f* ABINIT/ddkten
    1602              : !! NAME
    1603              : !! ddkten
    1604              : !!
    1605              : !! FUNCTION
    1606              : !! Compact or decompact the tensors related to the ffnl(:,1,...)
    1607              : !! part of the ddk operator, taking into account the direction
    1608              : !! of the ddk perturbation.
    1609              : !!
    1610              : !! INPUTS
    1611              : !!  compact= if 1, compact from tmpfac
    1612              : !!  idir=direction of the ddk perturbation
    1613              : !!  rank=0,1,2, or 3 = rank of tmpfac tensor, also angular momentum (=l)
    1614              : !!
    1615              : !! OUTPUT
    1616              : !!  (see side effects)
    1617              : !!
    1618              : !! SIDE EFFECTS
    1619              : !! Input/Output:
    1620              : !!  temp(2,(rank*(rank+1))/2)=compacted tensor
    1621              : !!    for l=1, just a scalar
    1622              : !!    for l=2, a vector
    1623              : !!  tmpfac(2,(rank+1)*(rank+2)/2)=decompacted tensor
    1624              : !!    for l=1, a vector
    1625              : !!    for l=2, a symmetric matrix, stored as
    1626              : !!     (1 . .)
    1627              : !!     (6 2 .)
    1628              : !!     (5 4 3)
    1629              : !!
    1630              : !! NOTES
    1631              : !! For l=0, there is no contribution.
    1632              : !!
    1633              : !! PARENTS
    1634              : !!      m_nonlop_pl
    1635              : !!
    1636              : !! CHILDREN
    1637              : !!
    1638              : !! SOURCE
    1639              : 
    1640      8661594 : subroutine ddkten(compact,idir,rank,temp,tmpfac)
    1641              : 
    1642              : !Arguments ------------------------------------
    1643              : !scalars
    1644              :  integer,intent(in) :: compact,idir,rank
    1645              : !arrays
    1646              :  real(dp),intent(inout) :: temp(2,(rank*(rank+1))/2)
    1647              :  real(dp),intent(inout) :: tmpfac(2,((rank+1)*(rank+2))/2)
    1648              : 
    1649              : !Local variables-------------------------------
    1650              : !scalars
    1651              :  character(len=500) :: msg
    1652              : 
    1653              : ! *************************************************************************
    1654              : 
    1655      8661594 :  if(rank/=1 .and. rank/=2 .and. rank/=3)then
    1656              :    write(msg, '(a,i10,a,a,a)' )&
    1657            0 :    'Input rank=',rank,' not allowed.',ch10,&
    1658            0 :    'Possible values are 1,2,3 only.'
    1659            0 :    ABI_BUG(msg)
    1660              :  end if
    1661              : 
    1662              : !Take care of p angular momentum
    1663      8661594 :  if(rank==1)then
    1664              : 
    1665              : !  Compaction tmpfac -> temp
    1666      4995510 :    if(compact==1)then
    1667      7493265 :      temp(:,1)=tmpfac(:,idir)
    1668              : 
    1669              : !    Decompaction temp -> tmpfac
    1670              :    else
    1671     24977550 :      tmpfac(:,1:3)=0.0d0
    1672      7493265 :      tmpfac(:,idir)=temp(:,1)
    1673              :    end if
    1674              : 
    1675              : !  Take care of d angular momentum
    1676              : !  rank=2 11->1 22->2 33->3 32->4 31->5 21->6
    1677              : 
    1678      3666084 :  else if(rank==2)then
    1679              : 
    1680              : !  Compaction tmpfac -> temp
    1681      3659324 :    if(compact==1)then
    1682      1829662 :      if(idir==1)then
    1683              : !      Count the number of non-zero derivatives with respect to k(idir)
    1684              : !      The factor of 2 on the diagonal comes from the derivative with
    1685              : !      respect to the first K then to the second K
    1686      7451982 :        temp(:,1)=2.0d0*tmpfac(:,1); temp(:,2)=tmpfac(:,6); temp(:,3)=tmpfac(:,5)
    1687      1001664 :      else if(idir==2)then
    1688      4527936 :        temp(:,2)=2.0d0*tmpfac(:,2); temp(:,1)=tmpfac(:,6); temp(:,3)=tmpfac(:,4)
    1689       498560 :      else if(idir==3)then
    1690      4487040 :        temp(:,3)=2.0d0*tmpfac(:,3); temp(:,1)=tmpfac(:,5); temp(:,2)=tmpfac(:,4)
    1691              :      end if
    1692              : !    Decompaction temp -> tmpfac
    1693              :    else
    1694     34763578 :      tmpfac(:,1:6)=0.0d0
    1695      5488986 :      tmpfac(:,idir)=2.0d0*temp(:,idir)
    1696      1829662 :      if(idir==1)then
    1697      4967988 :        tmpfac(:,5)=temp(:,3); tmpfac(:,6)=temp(:,2)
    1698      1001664 :      else if(idir==2)then
    1699      3018624 :        tmpfac(:,4)=temp(:,3); tmpfac(:,6)=temp(:,1)
    1700       498560 :      else if(idir==3)then
    1701      2991360 :        tmpfac(:,4)=temp(:,2); tmpfac(:,5)=temp(:,1)
    1702              :      end if
    1703              :    end if
    1704              : 
    1705              : !  Take care of f angular momentum
    1706         6760 :  else if(rank==3)then
    1707              : !  rank=3 111->1 221->2 331->3 321->4 311->5 211->6 222->7 332->8 322->9 333->10
    1708              : !  rank=2 11->1 22->2 33->3 32->4 31->5 21->6
    1709              : 
    1710              : !  Compaction tmpfac -> temp
    1711         6760 :    if(compact==1)then
    1712         3380 :      if(idir==1)then
    1713              : !      Count the number of non-zero derivatives with respect to k(idir)
    1714        10140 :        temp(:,1)=3.0d0*tmpfac(:,1)
    1715        33800 :        temp(:,2:4)=tmpfac(:,2:4)
    1716        23660 :        temp(:,5:6)=2.0d0*tmpfac(:,5:6)
    1717            0 :      else if(idir==2)then
    1718            0 :        temp(:,6)=2.0d0*tmpfac(:,2)
    1719            0 :        temp(:,4)=2.0d0*tmpfac(:,9)
    1720            0 :        temp(:,5)=tmpfac(:,4)
    1721            0 :        temp(:,1)=tmpfac(:,6)
    1722            0 :        temp(:,3)=tmpfac(:,8)
    1723            0 :        temp(:,2)=3.0d0*tmpfac(:,7)
    1724            0 :      else if(idir==3)then
    1725            0 :        temp(:,3)=3.0d0*tmpfac(:,10)
    1726            0 :        temp(:,5)=2.0d0*tmpfac(:,3)
    1727            0 :        temp(:,4)=2.0d0*tmpfac(:,8)
    1728            0 :        temp(:,6)=tmpfac(:,4)
    1729            0 :        temp(:,1)=tmpfac(:,5)
    1730            0 :        temp(:,2)=tmpfac(:,9)
    1731              :      end if
    1732              : !    Decompaction temp -> tmpfac
    1733              :    else
    1734       104780 :      tmpfac(:,1:10)=0.0d0
    1735         3380 :      if(idir==1)then
    1736        10140 :        tmpfac(:,1)=3.0d0*temp(:,1)
    1737        33800 :        tmpfac(:,2:4)=temp(:,2:4)
    1738        23660 :        tmpfac(:,5:6)=2.0d0*temp(:,5:6)
    1739            0 :      else if(idir==2)then
    1740            0 :        tmpfac(:,2)=2.0d0*temp(:,6)
    1741            0 :        tmpfac(:,9)=2.0d0*temp(:,4)
    1742            0 :        tmpfac(:,4)=temp(:,5)
    1743            0 :        tmpfac(:,6)=temp(:,1)
    1744            0 :        tmpfac(:,8)=temp(:,3)
    1745            0 :        tmpfac(:,7)=3.0d0*temp(:,2)
    1746            0 :      else if(idir==3)then
    1747            0 :        tmpfac(:,10)=3.0d0*temp(:,3)
    1748            0 :        tmpfac(:,3)=2.0d0*temp(:,5)
    1749            0 :        tmpfac(:,8)=2.0d0*temp(:,4)
    1750            0 :        tmpfac(:,4)=temp(:,6)
    1751            0 :        tmpfac(:,5)=temp(:,1)
    1752            0 :        tmpfac(:,9)=temp(:,2)
    1753              :      end if
    1754              :    end if
    1755              : 
    1756              :  end if
    1757              : 
    1758      8661594 : end subroutine ddkten
    1759              : !!***
    1760              : 
    1761              : end subroutine nonlop_pl
    1762              : !!***
    1763              : 
    1764              : end module m_nonlop_pl
    1765              : !!***
        

Generated by: LCOV version 2.3-1