LCOV - code coverage report
Current view: top level - src/95_drive - m_dfptlw_loop.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 94.4 % 538 508
Test Date: 2026-09-21 19:39:32 Functions: 100.0 % 3 3

            Line data    Source code
       1              : !!****m* ABINIT/m_dfptlw_loop
       2              : !! NAME
       3              : !!  m_dfptlw_loop
       4              : !!
       5              : !! FUNCTION
       6              : !!
       7              : !! COPYRIGHT
       8              : !!  Copyright (C) 2022-2026 ABINIT group (MR)
       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              : !! SOURCE
      14              : 
      15              : #if defined HAVE_CONFIG_H
      16              : #include "config.h"
      17              : #endif
      18              : 
      19              : #include "abi_common.h"
      20              : 
      21              : module m_dfptlw_loop
      22              : 
      23              :  use defs_basis
      24              :  use defs_wvltypes
      25              :  use m_errors
      26              :  use m_abicore
      27              :  use m_hdr
      28              :  use m_nctk
      29              :  use m_wffile
      30              :  use m_wfk
      31              :  use m_dtset
      32              :  use m_dtfil
      33              : 
      34              :  use defs_datatypes, only : pseudopotential_type
      35              :  use defs_abitypes, only : MPI_type
      36              :  use m_time,        only : timab
      37              :  use m_io_tools,    only : file_exists,iomode_from_fname,get_unit
      38              :  use m_kg,          only : getmpw,kpgio
      39              :  use m_inwffil,     only : inwffil
      40              :  use m_fft,         only : fourdp
      41              :  use m_ioarr,       only : read_rhor
      42              :  use m_hamiltonian, only : gs_hamiltonian_type
      43              :  use m_pawdij,      only : pawdij, pawdijfr, symdij
      44              :  use m_pawfgr,      only : pawfgr_type
      45              :  use m_pawfgrtab,   only : pawfgrtab_type
      46              :  use m_paw_an,      only : paw_an_type, paw_an_init, paw_an_free, paw_an_nullify, paw_an_reset_flags
      47              :  use m_paw_ij,      only : paw_ij_type, paw_ij_init, paw_ij_free, paw_ij_nullify, paw_ij_reset_flags, paw_ij_print
      48              :  use m_pawang,      only : pawang_type
      49              :  use m_pawrad,      only : pawrad_type
      50              :  use m_pawrhoij,    only : pawrhoij_type, pawrhoij_alloc, pawrhoij_free, pawrhoij_nullify, &
      51              : &                          pawrhoij_io, pawrhoij_inquire_dim
      52              :  use m_paw_nhat,    only : pawmknhat,pawnhatfr
      53              :  use m_paw_denpot,  only : pawdenpot
      54              :  use m_pawtab,      only : pawtab_type
      55              :  use m_rf2,         only : rf2_getidir
      56              :  use m_initylmg,    only : initylmg
      57              :  use m_atm2fft,     only : dfpt_atm2fft
      58              :  use m_dfpt_mkvxc,  only : dfpt_mkvxc, dfpt_mkvxcccdq
      59              :  use m_dfpt_rhotov, only : dfpt_rhotov
      60              :  use m_mkcore,      only : dfpt_mkcore
      61              :  use m_mklocl,      only : dfpt_vlocal, vlocalstr,dfpt_vlocaldq,dfpt_vlocaldqdq,dfpt_vmetdqdq
      62              :  use m_dfptlw_pert, only : dfptlw_pert
      63              :  use m_dfpttd_berrycurv, only : dfpttd_berrycurv
      64              :  use m_dynmat,      only : cart39
      65              :   use m_ebands  ,      only : ebands_t
      66              :  use m_xmpi
      67              : 
      68              :  implicit none
      69              : 
      70              :  private
      71              : !!***
      72              : 
      73              :  public :: dfptlw_loop
      74              : !!***
      75              : ! *************************************************************************
      76              : 
      77              : contains
      78              : !!***
      79              : 
      80              : !!****f* ABINIT/m_dfptlw_loop/dfptlw_loop
      81              : !! NAME
      82              : !! dfptlw_loop
      83              : !!
      84              : !! FUNCTION
      85              : !!  Loop over two perturbations j1, j2 and a q gradient
      86              : !!
      87              : !! INPUTS
      88              : !!  atindx(natom)=index table for atoms (see gstate.f)
      89              : !!  cg(2,mpw*nspinor*mband*mkmem*nsppol) = array for planewave coefficients of wavefunctions
      90              : !!  codvsn=code version
      91              : !!  d3e_pert1(mpert)=array with the i1pert cases to calculate
      92              : !!  d3e_pert2(mpert)=array with the i2pert cases to calculate
      93              : !!  dimffnl= third dimension of ffnl
      94              : !!  dtfil <type(datafiles_type)>=variables related to files
      95              : !!  dtset <type(dataset_type)>=all input variables for this dataset
      96              : !!  ffnl(dtset%mkmem,dtset%mpw,dimffnl,psps%lmnmax,psps%ntypat)= Nonlocal projectors and their derivatives
      97              : !!  gmet(3,3)=reciprocal space metric tensor in bohr**-2
      98              : !!  gprimd(3,3)=dimensional primitive translations for reciprocal space(bohr^-1)
      99              : !!  kg(3,mpw*mkmem)=reduced planewave coordinates
     100              : !!  kxc(nfftf,nkxc)=exchange-correlation kernel
     101              : !!  just_timdisp= it .true. this is a calculation of time-dispersion only
     102              : !!  mband = maximum number of bands
     103              : !!  mgfft = maximum single fft dimension
     104              : !!  mkmem = Number of k points treated by this node.
     105              : !!  mk1mem = Number of k points for first-order WF treated by this node.
     106              : !!  mpert =maximum number of ipert
     107              : !!  mpi_enreg=MPI-parallelisation information
     108              : !!  mpw   = maximum number of planewaves in basis sphere (large number)
     109              : !!  natom = number of atoms in unit cell
     110              : !!  nattyp(ntypat)= # atoms of each type.
     111              : !!  ncorespl(mqgrid_vl,2,ntypat)= spl interpolation of the pseudo core density for all atom types
     112              : !!  nfftf=(effective) number of FFT grid points (for this proc) for the "fine" grid (see NOTES in respfn.F90)
     113              : !!  ngfftf(1:18)=integer array with FFT box dimensions and other for the "fine" grid (see NOTES in respfn.F90)
     114              : !!  nkpt  = number of k points
     115              : !!  nkxc=second dimension of the array kxc, see rhotoxc.f for a description
     116              : !!  nspinor = number of spinorial components of the wavefunctions
     117              : !!  nsppol = number of channels for spin-polarization (1 or 2)
     118              : !!  npwarr(nkpt) = array holding npw for each k point
     119              : !!  nylmgr=second dimension of ylmgr_k
     120              : !!  occ(mband*nkpt*nsppol) = occupation number for each band and k
     121              : !!  pawfgr <type(pawfgr_type)>=fine grid parameters and related data
     122              : !!  pawtab(ntypat*usepaw) <type(pawtab_type)>=paw tabulated starting data
     123              : !!  psps <type(pseudopotential_type)> = variables related to pseudopotentials
     124              : !!  rfpert(3,mpert,3,mpert,3,mpert) = array defining the type of perturbations
     125              : !!       that have to be computed
     126              : !!       1   ->   element has to be computed explicitely
     127              : !!      -1   ->   use symmetry operations to obtain the corresponding element
     128              : !!  rhog(2,nfftf)=array for Fourier transform of GS electron density
     129              : !!  rhor(nfftf,nspden)=array for GS electron density in electrons/bohr**3.
     130              : !!  rmet(3,3)=real space metric tensor in bohr**2
     131              : !!  rprimd(3,3)=dimensional primitive translations (bohr)
     132              : !!  ucvol = unit cell volume (bohr^3)
     133              : !!  useylmgr= if 1 use the derivative of spherical harmonics
     134              : !!  xred(3,natom) = reduced atomic coordinates
     135              : !!  ylm(mpw*mkmem,psps%mpsang*psps%mpsang*psps%useylm)=real spherical harmonics
     136              : !!  ylmgr(mpw*mkmem,nylmgr,psps%mpsang*psps%mpsang*psps%useylm*useylmgr)= k-gradients of real spherical harmonics
     137              : !!
     138              : !! OUTPUT
     139              : !!  blkflg(3,mpert,3,mpert) = flags for each element of the 3DTE
     140              : !!                             (=1 if computed)
     141              : !!  d3etot(2,3,mpert,3,mpert,3,mpert) = third derivatives of the energy tensor
     142              : !!
     143              : !! SIDE EFFECTS
     144              : !!  hdr <type(hdr_type)>=the header of wf, den and pot files
     145              : !!
     146              : !! SOURCE
     147              : 
     148           17 : subroutine dfptlw_loop(atindx,blkflg,cg,codvsn,d3e_pert1,d3e_pert2,d3etot,dimffnl,dtfil,dtset,&
     149           17 : & ffnl,gmet,gprimd,gsqcut,&
     150           17 : & hdr,just_timdisp,kg,kxc,mband,mgfft,mkmem,mk1mem,&
     151           17 : & mpert,mpi_enreg,mpw,natom,nattyp,ncorespl,ngfftf,nfftf,nkpt,nkxc,nspinor,nsppol,&
     152           17 : & npwarr,nylmgr,occ,&
     153           17 : & pawfgr,pawtab,ph1d,&
     154           17 : & psps,rfpert,rhog,rhor,rmet,rprimd,ucvol,useylmgr,xred,ylm,ylmgr)
     155              : 
     156              : 
     157              : !Arguments ------------------------------------
     158              : !scalars
     159              :  integer,intent(in) :: dimffnl,mband,mgfft,mk1mem,mkmem,mpert,mpw,natom,nfftf
     160              :  integer,intent(in) :: nkpt,nkxc,nspinor,nsppol,nylmgr,useylmgr
     161              :  character(len=8),intent(in) :: codvsn
     162              :  logical,intent(in) :: just_timdisp
     163              :  real(dp),intent(in) :: gsqcut,ucvol
     164              :  type(MPI_type),intent(inout) :: mpi_enreg
     165              :  type(datafiles_type),intent(in) :: dtfil
     166              :  type(dataset_type),intent(in) :: dtset
     167              :  type(hdr_type),intent(inout) :: hdr
     168              :  type(pawfgr_type),intent(in) :: pawfgr
     169              :  type(pseudopotential_type),intent(in) :: psps
     170              : 
     171              : !arrays
     172              :  integer,intent(in) :: atindx(natom),d3e_pert1(mpert),d3e_pert2(mpert)
     173              :  integer,intent(in) :: kg(3,mk1mem*mpw)
     174              :  integer,intent(in) :: nattyp(psps%ntypat),ngfftf(18),npwarr(nkpt)
     175              :  integer,intent(in) :: rfpert(3,mpert,3,mpert,3,mpert)
     176              :  integer,intent(inout) :: blkflg(3,mpert,3,mpert,3,mpert)
     177              :  real(dp),intent(in) :: cg(2,mpw*nspinor*mband*mkmem*nsppol),gmet(3,3)
     178              :  real(dp),intent(in) :: ffnl(mkmem,mpw,dimffnl,psps%lmnmax,psps%ntypat)
     179              :  real(dp),intent(in) :: gprimd(3,3),kxc(nfftf,nkxc)
     180              :  real(dp),intent(in) :: ncorespl(psps%mqgrid_vl,2,psps%ntypat)
     181              :  real(dp),intent(in) :: ph1d(2,3*(2*mgfft+1)*natom)
     182              :  real(dp),intent(in) :: rhog(2,nfftf),rhor(nfftf,dtset%nspden),rmet(3,3),rprimd(3,3)
     183              :  real(dp),intent(in) :: xred(3,natom)
     184              :  real(dp),intent(inout) :: occ(mband*nkpt*nsppol)
     185              :  real(dp),intent(inout) :: d3etot(2,3,mpert,3,mpert,3,mpert)
     186              :  real(dp),intent(in) :: ylm(mpw*mkmem,psps%mpsang*psps%mpsang*psps%useylm)
     187              :  real(dp),intent(in) :: ylmgr(mpw*mkmem,nylmgr,psps%mpsang*psps%mpsang*psps%useylm*useylmgr)
     188              :  type(pawtab_type),intent(inout) :: pawtab(psps%ntypat*psps%usepaw)
     189              : 
     190              : !Local variables-------------------------------
     191              : !scalars
     192              :  integer :: alpha,ask_accurate,bantot,beta,comm_cell,cplex
     193              :  integer :: delta,dkdk_index,formeig,gamma
     194              :  integer :: ia1,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert,idir_dkdk
     195              :  integer :: idq,ierr,ii,ikpt,ireadwf,istr,itypat,mcg1,me,mpsang
     196              :  integer :: mpw1, mpw1_mq
     197              :  integer :: n1,n2,n3,ndir,n1dq,n2dq,nhat1grdim,nfftotf,nspden,n3xccc
     198              :  integer :: optgeom,opthartdqdq,optorth,pawread
     199              :  integer :: pert1case,pert2case,pert3case,timrev,usexcnhat
     200              :  integer :: pert1case_mq,pert2case_mq
     201              :  real(dp) :: delad,delag,delbd,delbg,ecut,ecut_eff
     202              :  logical :: finite_q,kramers_deg,samepert
     203              :  character(len=500) :: message
     204              :  character(len=fnlen) :: fiden1i,fiwf1i,fiwf2i,fiwfddk,fiwfdkdk
     205              :  character(len=fnlen) :: fiwf1i_mq,fiwf2i_mq
     206           17 :  type(gs_hamiltonian_type) :: gs_hamkq
     207              :  type(wffile_type) :: wff1,wff2,wfft1,wfft2
     208          187 :  type(wfk_t) :: ddk_f,d2_dkdk_f,d2_dkdk_f2
     209           17 :  type(wvl_data) :: wvl
     210           17 :  type(hdr_type) :: hdr_den
     211           17 :  type(ebands_t) :: ebands_kq,ebands_kmq
     212           17 :  type(hdr_type) :: hdr1_pq,hdr1_mq
     213           17 :  type(hdr_type) :: hdr2_pq,hdr2_mq
     214              : !arrays
     215              :  integer,save :: idx(18)=(/1,1,2,2,3,3,3,2,3,1,2,1,2,3,1,3,1,2/)
     216           17 :  integer,allocatable :: kg1(:,:),kg1_mq(:,:)
     217           17 :  integer,allocatable :: npwar1(:),npwar1_mq(:),npwtot1(:),npwtot1_mq(:)
     218              :  real(dp) :: d3etot_td(2),d3etot_td_mq(2)
     219           17 :  real(dp),allocatable :: cg1(:,:),cg2(:,:)
     220           17 :  real(dp),allocatable :: cg1_mq(:,:),cg2_mq(:,:)
     221           17 :  real(dp),allocatable :: d3etot_t4(:,:),d3etot_t5(:,:),d3etot_tgeom(:,:),eigen1(:),eigen2(:)
     222           17 :  real(dp),allocatable :: eigenq(:), doccde_tmp(:)
     223           17 :  real(dp),allocatable :: eigen1_mq(:),eigen2_mq(:)
     224           17 :  real(dp),allocatable :: kpq(:,:),kmq(:,:)
     225           17 :  real(dp),allocatable :: nhat1(:,:)
     226           17 :  real(dp),allocatable :: rho1g1(:,:),rho1r1(:,:)
     227           17 :  real(dp),allocatable :: rho2g1(:,:),rho2r1(:,:)
     228           17 :  real(dp),allocatable :: t4_typeI(:,:,:,:,:,:),t4_typeII(:,:,:,:,:,:,:)
     229           17 :  real(dp),allocatable :: t5_typeI(:,:,:,:,:,:),t5_typeII(:,:,:,:,:,:,:)
     230           17 :  real(dp),allocatable :: tgeom_typeI(:,:,:,:,:,:),tgeom_typeII(:,:,:,:,:,:,:)
     231           17 :  real(dp),allocatable :: vhart1dqdq(:),vpsp1dqdq(:)
     232           17 :  real(dp),allocatable :: vpsp1_i1pertdq(:,:,:),vpsp1_i2pertdq(:,:,:)
     233           17 :  real(dp),allocatable :: vxccc1_i2pertdq(:,:,:)
     234           17 :  real(dp),allocatable :: vpsp1_i1pertdq_geom(:,:,:), vpsp1_i1pertdqdq(:,:,:)
     235           17 :  real(dp),allocatable :: vxc1dqdq(:),work(:)
     236           17 :  real(dp),allocatable :: xccc3d2(:),xccc3d2dq(:)
     237           17 :  type(pawrhoij_type),allocatable :: pawrhoij_read(:)
     238              : 
     239              : 
     240              : ! *************************************************************************
     241              : 
     242              :  DBG_ENTER("COLL")
     243              : 
     244              : !Init parallelism
     245           17 :  comm_cell=mpi_enreg%comm_cell
     246           17 :  me=mpi_enreg%me_kpt
     247              : 
     248              : !Deactivate kramer's degeneracy for calculations that break TRS
     249              : !(finite q in magnetic materials or finite omega)
     250           17 :  kramers_deg=.true.
     251           17 :  timrev = 1
     252           17 :  if (dtset%tim1rev==0) then
     253            2 :    kramers_deg=.false.
     254            2 :    timrev = 0
     255              :  end if
     256              : 
     257              : !Special treatment for timdisp calculations at finite q
     258           17 :  finite_q=.false.
     259           68 :  if (sum(dtset%qptn(:)**2)>tol8) finite_q=.true.
     260              : 
     261              : !Various initializations
     262           17 :  cplex = 2 - timrev
     263           17 :  nspden = dtset%nspden
     264           17 :  ecut=dtset%ecut
     265           17 :  ecut_eff = ecut*(dtset%dilatmx)**2
     266           17 :  mpsang = psps%mpsang
     267           17 :  optorth=1;if (psps%usepaw==1) optorth=0
     268           17 :  opthartdqdq=1
     269              : 
     270              : !Set up some quantities required to calculate the Berry
     271              : !curvature at finite q
     272           51 :  ABI_MALLOC(npwar1,(dtset%nkpt))
     273           34 :  ABI_MALLOC(npwtot1,(dtset%nkpt))
     274           51 :  ABI_MALLOC(kpq,(3,dtset%nkpt))
     275           17 :  if (.not.kramers_deg) then
     276            4 :    ABI_MALLOC(npwar1_mq,(dtset%nkpt))
     277            4 :    ABI_MALLOC(npwtot1_mq,(dtset%nkpt))
     278            4 :    ABI_MALLOC(kmq,(3,dtset%nkpt))
     279              :  end if
     280           17 :  if (finite_q.or..not.kramers_deg) then
     281              : 
     282              :    !Initialize k+q (and k-q) array
     283           26 :    do ikpt=1,dtset%nkpt
     284           98 :      kpq(:,ikpt)=dtset%qptn(:)+dtset%kptns(:,ikpt)
     285              :    end do
     286            2 :    if (.not.kramers_deg) then
     287           26 :      do ikpt=1,nkpt
     288           98 :        kmq(:,ikpt)=-dtset%qptn(:)+dtset%kptns(:,ikpt)
     289              :      end do
     290              :    end if
     291              : 
     292              :    !Compute maximum number of planewaves at k+q (and k-q)
     293            2 :    call getmpw(ecut_eff,dtset%exchn2n3d,gmet,dtset%istwfk,kpq,mpi_enreg,mpw1,dtset%nkpt)
     294            2 :    if (.not.kramers_deg) then
     295            2 :      call getmpw(ecut_eff,dtset%exchn2n3d,gmet,dtset%istwfk,kmq,mpi_enreg,mpw1_mq,dtset%nkpt)
     296              :      !number of plane waves at k+q and k-q should be in principle the same to reconstruct rhor1_pq (?)
     297            2 :      mpw1=max(mpw1,mpw1_mq)
     298            2 :      mpw1_mq=mpw1
     299              :    else
     300            0 :      mpw1_mq=0
     301              :    end if
     302              : 
     303              :    !Set up the basis sphere of planewaves at k+q (and k-q)
     304            6 :    ABI_MALLOC(kg1,(3,mpw1*mk1mem))
     305              :    call kpgio(ecut_eff,dtset%exchn2n3d,gmet,dtset%istwfk,kg1,&
     306              :    &   kpq,mk1mem,dtset%nband,dtset%nkpt,'PERS',mpi_enreg,mpw1,&
     307            2 :    &   npwar1,npwtot1,dtset%nsppol)
     308            2 :    if (.not.kramers_deg) then
     309            6 :      ABI_MALLOC(kg1_mq,(3,mpw1_mq*mk1mem))
     310              :      call kpgio(ecut_eff,dtset%exchn2n3d,gmet,dtset%istwfk,kg1_mq,&
     311              :    & kmq,mk1mem,dtset%nband,dtset%nkpt,'PERS',mpi_enreg,mpw1_mq,&
     312            2 :    & npwar1_mq,npwtot1_mq,dtset%nsppol)
     313              :    end if
     314              : 
     315              : !  Initialize band structure datatype at k+q
     316           26 :    bantot=sum(dtset%nband(1:dtset%nkpt*dtset%nsppol))
     317            6 :    ABI_MALLOC(eigenq,(bantot))
     318            6 :    ABI_MALLOC(doccde_tmp,(dtset%mband*dtset%nkpt*dtset%nsppol))
     319         1010 :    eigenq(:)=zero
     320              :    call ebands_kq%init(bantot,dtset%nelect,dtset%ne_qFD,dtset%nh_qFD,dtset%ivalence,&
     321              : &   doccde_tmp,eigenq,dtset%istwfk,kpq,dtset%nband,dtset%nkpt,npwar1,dtset%nsppol,&
     322              : &   dtset%nspinor,dtset%tphysel,dtset%tsmear,dtset%occopt,occ,dtset%wtk,&
     323              : &   dtset%cellcharge(1), dtset%kptopt, dtset%kptrlatt_orig, dtset%nshiftk_orig, dtset%shiftk_orig, &
     324            2 : &   dtset%kptrlatt, dtset%nshiftk, dtset%shiftk)
     325            2 :    if (.not.kramers_deg) then
     326         1010 :      eigenq(:)=zero
     327              :      call ebands_kmq%init(bantot,dtset%nelect,dtset%ne_qFD,dtset%nh_qFD,dtset%ivalence,&
     328              : &     doccde_tmp,eigenq,dtset%istwfk,kmq,dtset%nband,dtset%nkpt,npwar1_mq,dtset%nsppol,&
     329              : &     dtset%nspinor,dtset%tphysel,dtset%tsmear,dtset%occopt,occ,dtset%wtk,&
     330              : &     dtset%cellcharge(1), dtset%kptopt, dtset%kptrlatt_orig, dtset%nshiftk_orig, dtset%shiftk_orig, &
     331            2 : &     dtset%kptrlatt, dtset%nshiftk, dtset%shiftk)
     332              :    end if
     333            2 :    ABI_FREE(eigenq)
     334            4 :    ABI_FREE(doccde_tmp)
     335              : 
     336              :  else
     337           45 :    ABI_MALLOC(kg1,(3,mpw*mk1mem))
     338         4158 :    kpq=dtset%kptns(:,1:dtset%nkpt)
     339           15 :    mpw1=mpw
     340       658542 :    kg1=kg
     341         1062 :    npwar1=npwarr
     342              :  end if
     343           17 :  mcg1=mpw1*nspinor*mband*mk1mem*nsppol
     344              : 
     345           51 :  ABI_MALLOC(cg1,(2,mcg1))
     346           34 :  ABI_MALLOC(cg2,(2,mcg1))
     347           51 :  ABI_MALLOC(eigen1,(2*dtset%mband*dtset%mband*dtset%nkpt*dtset%nsppol))
     348           34 :  ABI_MALLOC(eigen2,(2*dtset%mband*dtset%mband*dtset%nkpt*dtset%nsppol))
     349           17 :  if (.not.kramers_deg) then
     350            4 :    ABI_MALLOC(cg1_mq,(2,mcg1))
     351            4 :    ABI_MALLOC(cg2_mq,(2,mcg1))
     352            4 :    ABI_MALLOC(eigen1_mq,(2*dtset%mband*dtset%mband*dtset%nkpt*dtset%nsppol))
     353            4 :    ABI_MALLOC(eigen2_mq,(2*dtset%mband*dtset%mband*dtset%nkpt*dtset%nsppol))
     354              :  end if
     355           68 :  ABI_MALLOC(rho1r1,(cplex*nfftf,dtset%nspden))
     356           51 :  ABI_MALLOC(rho2r1,(cplex*nfftf,dtset%nspden))
     357           51 :  ABI_MALLOC(rho1g1,(2,nfftf))
     358           34 :  ABI_MALLOC(rho2g1,(2,nfftf))
     359              : 
     360           17 :  ask_accurate=1 ; formeig = 1 ; ireadwf = 1
     361           17 :  n1=ngfftf(1) ; n2=ngfftf(2) ; n3=ngfftf(3)
     362           17 :  nfftotf=n1*n2*n3
     363              : 
     364              : !Allocations for type-I terms
     365          119 :  ABI_MALLOC(t4_typeII,(2,3,mpert,3,mpert,3,mpert))
     366      6485593 :  t4_typeII(:,:,:,:,:,:,:)=zero
     367           17 :  if (d3e_pert2(natom+3)==1.or.d3e_pert2(natom+4)==1) then
     368           15 :    ABI_MALLOC(t4_typeI,(2,3,mpert,3,3,3))
     369         8234 :    t4_typeI(:,:,:,:,:,:)=zero
     370              :  end if
     371           68 :  ABI_MALLOC(t5_typeII,(2,3,mpert,3,mpert,3,mpert))
     372      6485593 :  t5_typeII(:,:,:,:,:,:,:)=zero
     373           17 :  if (d3e_pert1(natom+3)==1.or.d3e_pert1(natom+4)==1) then
     374            0 :    ABI_MALLOC(t5_typeI,(2,3,mpert,3,3,3))
     375           17 :    t5_typeI(:,:,:,:,:,:)=zero
     376              :  end if
     377           68 :  ABI_MALLOC(tgeom_typeII,(2,3,mpert,3,mpert,3,mpert))
     378      6485593 :  tgeom_typeII(:,:,:,:,:,:,:)=zero
     379           55 :  if (any(d3e_pert1(1:natom)==1).and.(d3e_pert2(natom+3)==1.or.d3e_pert2(natom+4)==1)) then
     380           15 :    ABI_MALLOC(tgeom_typeI,(2,3,mpert,3,3,3))
     381         8234 :    tgeom_typeI(:,:,:,:,:,:)=zero
     382              :  end if
     383              : 
     384              : 
     385              : !==== Initialize most of the Hamiltonian (and derivative) ====
     386              : !1) Allocate all arrays and initialize quantities that do not depend on k and spin.
     387              : !2) Perform the setup needed for the non-local factors:
     388              : !3) Norm-conserving: Constant kleimann-Bylander energies are copied from psps to gs_hamk.
     389              :  call gs_hamkq%init(psps,pawtab,dtset%nspinor,dtset%nsppol,nspden,dtset%natom,&
     390              : & dtset%typat,xred,dtset%nfft,mgfft,dtset%ngfft,rprimd,dtset%nloalg,ph1d=ph1d,&
     391           17 : & gpu_option=dtset%gpu_option)
     392              : 
     393              : !Specific allocations for strain-gradient perturbation
     394           17 :  if (dtset%lw_flexo==1.or.dtset%lw_flexo==2.or.dtset%lw_flexo==4) then
     395            9 :    ABI_MALLOC(vhart1dqdq,(2*nfftf))
     396            6 :    ABI_MALLOC(vpsp1dqdq,(2*nfftf))
     397            6 :    ABI_MALLOC(vxc1dqdq,(2*nfftf))
     398              :  end if
     399              : 
     400              : !Allocate xccc (only for quadrupoles yet)
     401           17 :  if (dtset%lw_qdrpl==1.and.psps%n1xccc/=0) then
     402            6 :    ABI_MALLOC(xccc3d2,(cplex*nfftf))
     403              :  end if
     404              : 
     405              : !This is necessary to deactivate paw options in the dfpt_rhotov routine
     406           17 :  ABI_MALLOC(pawrhoij_read,(0))
     407           17 :  usexcnhat=0
     408           17 :  n3xccc=0;if(psps%n1xccc/=0)n3xccc=nfftf
     409           17 :  pawread=0
     410           17 :  nhat1grdim=0
     411           68 :  ABI_MALLOC(nhat1,(cplex*dtset%nfft,nspden))
     412       223617 :  nhat1=zero
     413              : 
     414              : 
     415           17 :  pert1case = 0 ; pert2case = 0 ; pert3case = 0
     416           17 :  pert1case_mq = 0 ; pert2case_mq = 0
     417              : 
     418          259 :  do i1pert = 1, mpert
     419          985 :    do i1dir = 1, 3
     420              : 
     421      2623064 :      if ((maxval(rfpert(i1dir,i1pert,:,:,:,:))==1)) then
     422              : 
     423           55 :        if (i1pert < natom + 10) then
     424           52 :          pert1case = i1dir + (i1pert-1)*3
     425            3 :        else if (i1pert > natom+11 .and. i1pert <= 2*natom+11) then
     426            3 :          pert1case = i1dir + i1pert*3
     427              :        end if
     428           55 :        call appdig(pert1case,dtfil%fnamewff1,fiwf1i)
     429              : 
     430           55 :        if (finite_q) then
     431              :          call hdr1_pq%init(ebands_kq,codvsn,dtset,pawtab,pert1case,psps,wvl%descr, &
     432            4 :        & comm_atom=mpi_enreg%comm_atom,mpi_atmtab=mpi_enreg%my_atmtab )
     433              :        else
     434           51 :          hdr1_pq=hdr
     435              :        end if
     436              : 
     437              :        call inwffil(ask_accurate,cg1,dtset,dtset%ecut,ecut_eff,eigen1,dtset%exchn2n3d,&
     438              :        & formeig,hdr1_pq,ireadwf,dtset%istwfk,kg1,kpq,dtset%localrdwf,&
     439              :        & dtset%mband,mcg1,dtset%mk1mem,mpi_enreg,mpw1,&
     440              :        & dtset%nband,dtset%ngfft,dtset%nkpt,npwar1,&
     441              :        & dtset%nsppol,dtset%nsym,&
     442              :        & occ,optorth,dtset%symafm,dtset%symrel,dtset%tnons,&
     443           55 :        & dtfil%unkg1,wff1,wfft1,dtfil%unwff1,fiwf1i,wvl)
     444              : 
     445           55 :        if (ireadwf==1) then
     446           55 :          call WffClose (wff1,ierr)
     447              :        end if
     448              : 
     449           55 :        if (.not.kramers_deg) then
     450            4 :          if (finite_q) then
     451            4 :            pert1case_mq=pert1case+(2*dtset%natom+11)*3
     452              :          else
     453            0 :            pert1case_mq=pert1case
     454              :          endif
     455            4 :          call appdig(pert1case_mq,dtfil%fnamewff1,fiwf1i_mq)
     456              : 
     457            4 :          if (finite_q) then
     458              :            call hdr1_mq%init(ebands_kmq,codvsn,dtset,pawtab,pert1case_mq,psps,wvl%descr, &
     459            4 :          & comm_atom=mpi_enreg%comm_atom,mpi_atmtab=mpi_enreg%my_atmtab )
     460              :          else
     461            0 :            hdr1_mq=hdr
     462              :          end if
     463              : 
     464              :          call inwffil(ask_accurate,cg1_mq,dtset,dtset%ecut,ecut_eff,eigen1_mq,dtset%exchn2n3d,&
     465              :          & formeig,hdr1_mq,ireadwf,dtset%istwfk,kg1_mq,kmq,dtset%localrdwf,&
     466              :          & dtset%mband,mcg1,dtset%mk1mem,mpi_enreg,mpw1,&
     467              :          & dtset%nband,dtset%ngfft,dtset%nkpt,npwar1_mq,&
     468              :          & dtset%nsppol,dtset%nsym,&
     469              :          & occ,optorth,dtset%symafm,dtset%symrel,dtset%tnons,&
     470            4 :          & dtfil%unkg1,wff1,wfft1,dtfil%unwff1,fiwf1i_mq,wvl)
     471              : 
     472            4 :          if (ireadwf==1) then
     473            4 :            call WffClose (wff1,ierr)
     474              :          end if
     475              :        end if
     476              : 
     477           55 :        if (.not.just_timdisp) then
     478           43 :          call read_1eig(eigen1,formeig,mband,nkpt,nsppol,fiwf1i)
     479              : 
     480      1377834 :          rho1r1(:,:) = zero; rho1g1(:,:) = zero
     481           43 :          if (dtset%get1den /= 0 .or. dtset%ird1den /= 0) then
     482           43 :            call appdig(pert1case,dtfil%fildens1in,fiden1i)
     483              : 
     484              :            call read_rhor(fiden1i, cplex, dtset%nspden, nfftf, ngfftf, psps%usepaw, mpi_enreg, rho1r1, &
     485           43 :            hdr_den, pawrhoij_read, comm_cell, check_hdr=hdr)
     486           43 :            call hdr_den%free()
     487              :          end if
     488              : 
     489              :          !Perform FFT rhor1 to rhog1
     490          129 :          ABI_MALLOC(work,(cplex*nfftf))
     491       344480 :          work(:)=rho1r1(:,1)
     492           43 :          call fourdp(cplex,rho1g1,work,-1,mpi_enreg,dtset%nfft,1,dtset%ngfft,0)
     493           43 :          ABI_FREE(work)
     494              :        end if
     495              : 
     496              :        !Allocate the first-order gradient local potential
     497           55 :        if (i1pert <= natom+3) then
     498           49 :          n1dq=1
     499          196 :          ABI_MALLOC(vpsp1_i1pertdq,(2*nfftf,dtset%nspden,n1dq))
     500            6 :        else if (i1pert == natom+4) then
     501            0 :          n1dq=2
     502            0 :          ABI_MALLOC(vpsp1_i1pertdq,(2*nfftf,dtset%nspden,n1dq))
     503              :        else
     504            6 :          n1dq=1
     505              :        end if
     506          165 :        ABI_MALLOC(d3etot_t5,(2,n1dq))
     507              : 
     508          737 :        do i2pert = 1, mpert
     509         2783 :          do i2dir = 1, 3
     510              : 
     511       117016 :            if ((maxval(rfpert(i1dir,i1pert,i2dir,i2pert,:,:))==1)) then
     512              : 
     513          242 :              if (i2pert < natom + 10) then
     514          236 :                pert2case = i2dir + (i2pert-1)*3
     515            6 :              else if (i2pert > natom+11 .and. i2pert <= 2*natom+11) then
     516            6 :                pert2case = i2dir + i2pert*3
     517              :              end if
     518              : 
     519          242 :              call appdig(pert2case,dtfil%fnamewff1,fiwf2i)
     520              : 
     521          242 :              if (finite_q) then
     522              :                call hdr2_pq%init(ebands_kq,codvsn,dtset,pawtab,pert2case,psps,wvl%descr, &
     523            6 :              & comm_atom=mpi_enreg%comm_atom,mpi_atmtab=mpi_enreg%my_atmtab )
     524              :              else
     525          236 :                hdr2_pq=hdr
     526              :              end if
     527              : 
     528              :              call inwffil(ask_accurate,cg2,dtset,dtset%ecut,ecut_eff,eigen2,dtset%exchn2n3d,&
     529              :              & formeig,hdr2_pq,ireadwf,dtset%istwfk,kg1,kpq,dtset%localrdwf,&
     530              :              & dtset%mband,mcg1,dtset%mk1mem,mpi_enreg,mpw1,&
     531              :              & dtset%nband,dtset%ngfft,dtset%nkpt,npwar1,&
     532              :              & dtset%nsppol,dtset%nsym,&
     533              :              & occ,optorth,dtset%symafm,dtset%symrel,dtset%tnons,&
     534          242 :              & dtfil%unkg1,wff2,wfft2,dtfil%unwff2,fiwf2i,wvl)
     535              : 
     536          242 :              if (ireadwf==1) then
     537          242 :                call WffClose (wff2,ierr)
     538              :              end if
     539              : 
     540          242 :              if (.not.kramers_deg) then
     541            6 :                if (finite_q) then
     542            6 :                  pert2case_mq=pert2case+(2*dtset%natom+11)*3
     543              :                else
     544            0 :                  pert2case_mq=pert2case
     545              :                end if
     546            6 :                call appdig(pert2case_mq,dtfil%fnamewff1,fiwf2i_mq)
     547              : 
     548            6 :                if (finite_q) then
     549              :                  call hdr2_mq%init(ebands_kmq,codvsn,dtset,pawtab,pert2case_mq,psps,wvl%descr, &
     550            6 :                & comm_atom=mpi_enreg%comm_atom,mpi_atmtab=mpi_enreg%my_atmtab )
     551              :                else
     552            0 :                  hdr2_mq=hdr
     553              :                end if
     554              : 
     555              :                call inwffil(ask_accurate,cg2_mq,dtset,dtset%ecut,ecut_eff,eigen2_mq,dtset%exchn2n3d,&
     556              :                & formeig,hdr2_mq,ireadwf,dtset%istwfk,kg1_mq,kmq,dtset%localrdwf,&
     557              :                & dtset%mband,mcg1,dtset%mk1mem,mpi_enreg,mpw1,&
     558              :                & dtset%nband,dtset%ngfft,dtset%nkpt,npwar1_mq,&
     559              :                & dtset%nsppol,dtset%nsym,&
     560              :                & occ,optorth,dtset%symafm,dtset%symrel,dtset%tnons,&
     561            6 :                & dtfil%unkg1,wff2,wfft2,dtfil%unwff2,fiwf2i_mq,wvl)
     562              : 
     563            6 :                if (ireadwf==1) then
     564            6 :                  call WffClose (wff2,ierr)
     565              :                end if
     566              :              end if
     567              : 
     568          242 :              if (i1pert==i2pert.and.i1dir==i2dir) then
     569           14 :                samepert=.true.
     570              :              else
     571          228 :                samepert=.false.
     572              :              end if
     573              : 
     574          242 :              if (.not.just_timdisp) then
     575          222 :                call read_1eig(eigen2,formeig,mband,nkpt,nsppol,fiwf2i)
     576              : 
     577      5990380 :                rho2r1(:,:) = zero; rho2g1(:,:) = zero
     578          222 :                if (dtset%get1den /= 0 .or. dtset%ird1den /= 0) then
     579          222 :                  call appdig(pert2case,dtfil%fildens1in,fiden1i)
     580              : 
     581              :                  call read_rhor(fiden1i, cplex, dtset%nspden, nfftf, ngfftf, psps%usepaw, mpi_enreg, rho2r1, &
     582          222 :                  hdr_den, pawrhoij_read, comm_cell, check_hdr=hdr)
     583          222 :                  call hdr_den%free()
     584              :                end if
     585              : 
     586          222 :                if (.not.samepert) then
     587              :                  !Perform FFT rhor1 to rhog1
     588          654 :                  ABI_MALLOC(work,(cplex*nfftf))
     589      1473753 :                  work(:)=rho2r1(:,1)
     590          218 :                  call fourdp(cplex,rho2g1,work,-1,mpi_enreg,dtset%nfft,1,dtset%ngfft,0)
     591          218 :                  ABI_FREE(work)
     592              :                end if !samepert
     593              :              end if
     594              : 
     595              :              !Allocate the first-order gradient local potential
     596          242 :              if (i2pert <= natom+3) then
     597          149 :                n2dq=1
     598          596 :                ABI_MALLOC(vpsp1_i2pertdq,(2*nfftf,dtset%nspden,n2dq))
     599          596 :                ABI_MALLOC(vxccc1_i2pertdq,(2*nfftf,dtset%nspden,n2dq))
     600          447 :                ABI_MALLOC(xccc3d2dq,(2*nfftf))
     601           93 :              else if (i2pert == natom+4) then
     602           81 :                n2dq=2
     603          405 :                ABI_MALLOC(vpsp1_i2pertdq,(2*nfftf,dtset%nspden,n2dq))
     604              :              else
     605           12 :                n2dq=1
     606              :              end if
     607          726 :              ABI_MALLOC(d3etot_t4,(2,n2dq))
     608          484 :              ABI_MALLOC(d3etot_tgeom,(2,n2dq))
     609              : 
     610              :              !Calculate the first-order gradient local potential that enters the geometric term
     611         1210 :              ABI_MALLOC(vpsp1_i1pertdq_geom,(2*nfftf,dtset%nspden,3))
     612          242 :              if (.not.just_timdisp) then
     613          222 :                if (i1pert <= natom .and. (i2pert == natom+3.or.i2pert == natom+4)) then
     614              : 
     615              :                  !calculate the second of the two first-gradient directions
     616          432 :                  do ii=1,3
     617              :                    call dfpt_vlocaldq(atindx,2,gmet,gsqcut,i1dir,i1pert,mpi_enreg, &
     618              :                    & psps%mqgrid_vl,dtset%natom,nattyp,dtset%nfft,dtset%ngfft,dtset%ntypat,n1,n2,n3, &
     619          546 :                    & ph1d,ii,psps%qgrid_vl,dtset%qptn,ucvol,psps%vlspl,vpsp1_i1pertdq_geom(:,1,ii))
     620              :                  end do
     621              :                end if
     622              :              end if
     623              : 
     624              :              !Allocate the second-gradient array
     625         1210 :              ABI_MALLOC(vpsp1_i1pertdqdq,(2*nfftf,dtset%nspden,n2dq))
     626              : 
     627              :              !Calculate first-order pseudocore charge (still, only for quadrupoles)
     628          242 :              if (.not.just_timdisp) then
     629          222 :                if (i1pert==natom+2.and.i2pert<=natom.and.psps%n1xccc/=0.and.nkxc == 7) then
     630            9 :                  if (psps%nc_xccc_gspace==1) then
     631            0 :                    ndir=1
     632              :                    call dfpt_atm2fft(atindx,cplex,gmet,gprimd,gsqcut,i2dir,i2pert,&
     633              :                    & mgfft,psps%mqgrid_vl,dtset%natom,ndir,nfftf,ngfftf,psps%ntypat,&
     634              :                    & ph1d,psps%qgrid_vl,dtset%qptn,dtset%typat,ucvol,psps%usepaw,xred,psps,pawtab,&
     635            0 :                    & atmrhor1=xccc3d2,optn_in=n3xccc/nfftf,optn2_in=1)
     636            9 :                  else if (psps%nc_xccc_gspace==0) then
     637              :                    call dfpt_mkcore(cplex,i2dir,i2pert,dtset%natom,psps%ntypat,n1,psps%n1xccc,&
     638            9 :                    & n2,n3,dtset%qptn,rprimd,dtset%typat,ucvol,psps%xcccrc,psps%xccc1d,xccc3d2,xred)
     639              :                  end if
     640              :                end if
     641              :              end if
     642              : 
     643         2898 :              do i3pert = 1, mpert
     644        10866 :                do i3dir = 1, 3
     645              : 
     646        10624 :                  if (rfpert(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)==1) then
     647              : 
     648          611 :                    blkflg(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert) = 1
     649              : 
     650              :                    !Calculate local potentials for first-order gradient Hamiltonians
     651              :                    !gradient of i1pert:
     652          611 :                    if (.not.just_timdisp) then
     653          591 :                      if (i1pert<=natom) then
     654              :                        !Get q-gradient of first-order local part of the pseudopotential
     655              :                        call dfpt_vlocaldq(atindx,2,gmet,gsqcut,i1dir,i1pert,mpi_enreg, &
     656              :                        & psps%mqgrid_vl,dtset%natom,nattyp,dtset%nfft,dtset%ngfft,dtset%ntypat,n1,n2,n3, &
     657          354 :                        & ph1d,i3dir,psps%qgrid_vl,dtset%qptn,ucvol,psps%vlspl,vpsp1_i1pertdq(:,1,1))
     658              : 
     659          354 :                        if (i2pert == natom+3.or.i2pert == natom+4) then
     660          324 :                          gamma=i3dir
     661          810 :                          do idq= 1, n2dq
     662          486 :                             if (i2pert==natom+3) then
     663          162 :                               istr=i2dir
     664              :                             else
     665          324 :                               istr=idq*3+i2dir
     666              :                             endif
     667          486 :                             delta=idx(2*istr)
     668              :                             call dfpt_vlocaldqdq(atindx,2,gs_hamkq%gmet,gsqcut,i1dir,i1pert,mpi_enreg, &
     669              :                           & psps%mqgrid_vl,dtset%natom,&
     670              :                           & nattyp,dtset%nfft,dtset%ngfft,dtset%ntypat,n1,n2,n3, &
     671              :                           & ph1d,gamma,delta,psps%qgrid_vl,&
     672          840 :                           & dtset%qptn,ucvol,psps%vlspl,vpsp1_i1pertdqdq(:,1,idq))
     673              :                          end do
     674              :                        end if
     675              : 
     676          237 :                      else if (i1pert==natom+3.or.i1pert==natom+4) then
     677            0 :                        istr=i1dir; if (i1pert==natom+4) istr=3+i1dir
     678              :                        !Get 2nd q-gradient of first-order local part of the pseudopotential and of the Hartree
     679              :                        !(and XC if GGA) contribution from ground state density
     680              :                        call dfpt_vmetdqdq(2,gmet,gprimd,gsqcut,istr,i1pert,kxc,mpi_enreg, &
     681              :                        & psps%mqgrid_vl,natom,nattyp,dtset%nfft,dtset%ngfft,dtset%ntypat,n1,n2,n3,&
     682              :                        & nkxc,nspden,opthartdqdq,ph1d,i3dir,psps%qgrid_vl,&
     683            0 :                        & dtset%qptn,rhog,rhor,ucvol,psps%vlspl,vhart1dqdq,vpsp1dqdq,vxc1dqdq)
     684            0 :                        vpsp1_i1pertdq(:,1,1)=vhart1dqdq(:)+vpsp1dqdq(:)+vxc1dqdq(:)
     685            0 :                        if (i1pert==natom+4) then
     686              :                          !Here we need to calculate both extradiagonal shear-strains
     687              :                          !because the second gradient of the metric perturbation is
     688              :                          !type-I, i.e., non symmetric with respect to the
     689              :                          !permutation of the strain indexes.
     690            0 :                          istr=6+i1dir
     691              :                          call dfpt_vmetdqdq(2,gmet,gprimd,gsqcut,istr,i1pert,kxc,mpi_enreg, &
     692              :                          & psps%mqgrid_vl,natom,nattyp,dtset%nfft,dtset%ngfft,dtset%ntypat,n1,n2,n3,&
     693              :                          & nkxc,nspden,opthartdqdq,ph1d,i3dir,psps%qgrid_vl,&
     694            0 :                          & dtset%qptn,rhog,rhor,ucvol,psps%vlspl,vhart1dqdq,vpsp1dqdq,vxc1dqdq)
     695            0 :                          vpsp1_i1pertdq(:,1,2)=vhart1dqdq(:)+vpsp1dqdq(:)+vxc1dqdq(:)
     696              :                        end if
     697              :                      end if
     698              : 
     699          591 :                      if (.not.samepert) then
     700              :                        !gradient of i2pert:
     701          584 :                        if (i2pert<=natom) then
     702              :                          !Get q-gradient of first-order local part of the pseudopotential
     703              :                          call dfpt_vlocaldq(atindx,2,gmet,gsqcut,i2dir,i2pert,mpi_enreg, &
     704              :                          & psps%mqgrid_vl,dtset%natom,nattyp,dtset%nfft,dtset%ngfft,dtset%ntypat,n1,n2,n3, &
     705           94 :                          & ph1d,i3dir,psps%qgrid_vl,dtset%qptn,ucvol,psps%vlspl,vpsp1_i2pertdq(:,1,1))
     706          490 :                        else if (i2pert==natom+3.or.i2pert==natom+4) then
     707          486 :                          istr=i2dir; if (i2pert==natom+4) istr=3+i2dir
     708              :                          !Get 2nd q-gradient of first-order local part of the pseudopotential and of the Hartree
     709              :                          !(and XC if GGA) contribution from ground state density
     710              :                          call dfpt_vmetdqdq(2,gmet,gprimd,gsqcut,istr,i2pert,kxc,mpi_enreg, &
     711              :                          & psps%mqgrid_vl,natom,nattyp,dtset%nfft,dtset%ngfft,dtset%ntypat,n1,n2,n3,&
     712              :                          & nkxc,nspden,opthartdqdq,ph1d,i3dir,psps%qgrid_vl,&
     713          486 :                          & dtset%qptn,rhog,rhor,ucvol,psps%vlspl,vhart1dqdq,vpsp1dqdq,vxc1dqdq)
     714      3280986 :                          vpsp1_i2pertdq(:,1,1)=vhart1dqdq(:)+vpsp1dqdq(:)+vxc1dqdq(:)
     715          486 :                          if (i2pert==natom+4) then
     716              :                            !Here we need to calculate both extradiagonal shear-strains
     717              :                            !because the second gradient of the metric perturbation is
     718              :                            !type-I, i.e., non symmetric with respect to the
     719              :                            !permutation of the strain indexes.
     720          243 :                            istr=6+i2dir
     721              :                            call dfpt_vmetdqdq(2,gmet,gprimd,gsqcut,istr,i2pert,kxc,mpi_enreg, &
     722              :                            & psps%mqgrid_vl,natom,nattyp,dtset%nfft,dtset%ngfft,dtset%ntypat,n1,n2,n3,&
     723              :                            & nkxc,nspden,opthartdqdq,ph1d,i3dir,psps%qgrid_vl,&
     724          243 :                            & dtset%qptn,rhog,rhor,ucvol,psps%vlspl,vhart1dqdq,vpsp1dqdq,vxc1dqdq)
     725      1640493 :                            vpsp1_i2pertdq(:,1,2)=vhart1dqdq(:)+vpsp1dqdq(:)+vxc1dqdq(:)
     726              :                          end if
     727              :                        end if
     728              : 
     729          584 :                        if (i1pert==natom+2.and.i2pert<=natom.and.psps%n1xccc/=0) then
     730              :                          !Get the q-gradient of the pseudocore density
     731              :                          call dfpt_vlocaldq(atindx,2,gmet,gsqcut,i2dir,i2pert,mpi_enreg, &
     732              :                          & psps%mqgrid_vl,dtset%natom,nattyp,dtset%nfft,dtset%ngfft,dtset%ntypat,n1,n2,n3, &
     733           27 :                          & ph1d,i3dir,psps%qgrid_vl,dtset%qptn,ucvol,ncorespl,xccc3d2dq,optnc=1)
     734              : 
     735              :                          !Get the q-gradient of the first-order XC potential due to the pseudocore charge
     736              :                          call dfpt_mkvxcccdq(cplex,i3dir,dtset%ixc,gprimd,kxc,mpi_enreg,nfftf,dtset%ngfft,&
     737           27 :                        & nkxc,nspden,dtset%qptn,rprimd,vxccc1_i2pertdq,xccc3d2,xccc3d2dq)
     738              : 
     739              :                          !Add this contribution to the gradient of the local PSP
     740       244716 :                          vpsp1_i2pertdq= vpsp1_i2pertdq + vxccc1_i2pertdq
     741              :                        end if
     742              :                      end if !samepert
     743              : 
     744              : 
     745              :                      !Prepare ddk wf file
     746          591 :                      pert3case = i3dir + natom*3
     747          591 :                      call appdig(pert3case,dtfil%fnamewffddk,fiwfddk)
     748              :                      ! Checking the existence of data file
     749          591 :                      if (.not. file_exists(fiwfddk)) then
     750              :                        ! Trick needed to run Abinit test suite in netcdf mode.
     751          591 :                        if (file_exists(nctk_ncify(fiwfddk))) then
     752          591 :                          write(message,"(3a)")"- File: ",trim(fiwfddk),&
     753         1182 :                          " does not exist but found netcdf file with similar name."
     754          591 :                          call wrtout(std_out,message,'COLL')
     755         1182 :                          fiwfddk = nctk_ncify(fiwfddk)
     756              :                        end if
     757          591 :                        if (.not. file_exists(fiwfddk)) then
     758            0 :                          ABI_ERROR('Missing file: '//TRIM(fiwfddk))
     759              :                        end if
     760              :                      end if
     761          591 :                      write(message,'(2a)')'-dfptlw_loop : read the ddk wavefunctions from file: ',trim(fiwfddk)
     762          591 :                      call wrtout(std_out,message,'COLL')
     763              :                      !call wrtout(ab_out,message,'COLL')
     764              :                      !Note that the unit number for these files is 50,51,52 or 53 (dtfil%unddk=50)
     765          591 :                      call ddk_f%open_read(fiwfddk,1,dtset%iomode,dtfil%unddk,mpi_enreg%comm_cell)
     766              : 
     767              :                      !Prepare d2_dkdk wf file
     768              :                      !For i1pert
     769          591 :                      if (i1pert==natom+2) then
     770          237 :                        call rf2_getidir(i1dir,i3dir,idir_dkdk)
     771              :                        !if (idir_dkdk>6) idir_dkdk=idir_dkdk-3
     772          237 :                        dkdk_index=idir_dkdk+(dtset%natom+6)*3
     773          237 :                        call appdig(dkdk_index,dtfil%fnamewffdkdk,fiwfdkdk)
     774              :                        !Check that d2_dkdk file exists and open it
     775          237 :                        if (.not. file_exists(fiwfdkdk)) then
     776              :                          ! Trick needed to run Abinit test suite in netcdf mode.
     777          237 :                          if (file_exists(nctk_ncify(fiwfdkdk))) then
     778          237 :                            write(message,"(3a)")"- File: ",trim(fiwfdkdk),&
     779          474 :                            " does not exist but found netcdf file with similar name."
     780          237 :                            call wrtout(std_out,message,'COLL')
     781          474 :                            fiwfdkdk = nctk_ncify(fiwfdkdk)
     782              :                          end if
     783          237 :                          if (.not. file_exists(fiwfdkdk)) then
     784            0 :                            ABI_ERROR('Missing file: '//TRIM(fiwfdkdk))
     785              :                          end if
     786              :                        end if
     787          237 :                        write(message,'(2a)')'-dfptlw_loop : read the d2_dkdk wavefunctions from file: ',trim(fiwfdkdk)
     788          237 :                        call wrtout(std_out,message,'COLL')
     789              :                        !call wrtout(ab_out,message,'COLL')
     790          237 :                        call d2_dkdk_f%open_read(fiwfdkdk,1,dtset%iomode,dtfil%unddk+1,mpi_enreg%comm_cell)
     791              : 
     792              :                      end if
     793              : 
     794              :                      !Prepare d2_dkdk wf file
     795              :                      !For i2pert
     796          591 :                      if (i2pert==natom+2.and..not.samepert) then
     797            4 :                        call rf2_getidir(i2dir,i3dir,idir_dkdk)
     798              :                        !if (idir_dkdk>6) idir_dkdk=idir_dkdk-3
     799            4 :                        dkdk_index=idir_dkdk+(dtset%natom+6)*3
     800            4 :                        call appdig(dkdk_index,dtfil%fnamewffdkdk,fiwfdkdk)
     801              :                        !Check that d2_dkdk file exists and open it
     802            4 :                        if (.not. file_exists(fiwfdkdk)) then
     803              :                          ! Trick needed to run Abinit test suite in netcdf mode.
     804            4 :                          if (file_exists(nctk_ncify(fiwfdkdk))) then
     805            4 :                            write(message,"(3a)")"- File: ",trim(fiwfdkdk),&
     806            8 :                            " does not exist but found netcdf file with similar name."
     807            4 :                            call wrtout(std_out,message,'COLL')
     808            8 :                            fiwfdkdk = nctk_ncify(fiwfdkdk)
     809              :                          end if
     810            4 :                          if (.not. file_exists(fiwfdkdk)) then
     811            0 :                            ABI_ERROR('Missing file: '//TRIM(fiwfdkdk))
     812              :                          end if
     813              :                        end if
     814            4 :                        write(message,'(2a)')'-dfptlw_loop : read the d2_dkdk wavefunctions from file: ',trim(fiwfdkdk)
     815            4 :                        call wrtout(std_out,message,'COLL')
     816            4 :                        call d2_dkdk_f2%open_read(fiwfdkdk,1,dtset%iomode,dtfil%unddk+2,mpi_enreg%comm_cell)
     817              :                      end if
     818              : 
     819              :                      !Perform the longwave DFPT part of the 3dte calculation
     820              :                      call dfptlw_pert(cg,cg1,cg2,cplex,d3etot,d3etot_t4,d3etot_t5,d3etot_tgeom,dimffnl,dtset, &
     821              :                      & eigen1,eigen2,ffnl,gmet,gs_hamkq,gsqcut,i1dir,&
     822              :                      & i2dir,i3dir,i1pert,i2pert,i3pert,kg,kxc,mband,mkmem,mk1mem,mpert,mpi_enreg,&
     823              :                      & mpsang,mpw1,natom,n1dq,n2dq,nfftf,ngfftf,nkpt,nkxc,nspden,nspinor,nsppol,npwarr,nylmgr,occ,&
     824              :                      & pawfgr,psps,rho1g1,rho1r1,rho2r1,rmet,rprimd,samepert,ucvol,useylmgr,&
     825              :                      & vpsp1_i1pertdq,vpsp1_i1pertdqdq,vpsp1_i1pertdq_geom,vpsp1_i2pertdq,&
     826          591 :                      & ddk_f,d2_dkdk_f,d2_dkdk_f2,ylm,ylmgr)
     827              : 
     828              :                      !close ddk file
     829          591 :                      call ddk_f%close()
     830              : 
     831              :                      !close d2_dkdk file (i1pert)
     832          591 :                      if (i1pert==natom+2) call d2_dkdk_f%close()
     833              : 
     834              :                      ! Close d2_dkdk file (i2pert)
     835          591 :                      if (i2pert==natom+2.and..not.samepert) call d2_dkdk_f2%close()
     836              : 
     837              :                      !Save the type-I terms
     838          591 :                      if (i2pert==natom+3.or.i2pert==natom+4) then
     839          486 :                        gamma=i3dir
     840         1215 :                        do idq=1,n2dq
     841          729 :                          if (i2pert==natom+3) then
     842          243 :                            istr=i2dir
     843              :                          else
     844          486 :                            istr=idq*3+i2dir
     845              :                          endif
     846          729 :                          beta=idx(2*istr-1); delta=idx(2*istr)
     847         2673 :                          t4_typeI(:,i1dir,i1pert,beta,delta,gamma)=d3etot_t4(:,idq)
     848              :                        end do
     849              :                      else
     850          315 :                        t4_typeII(:,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)=d3etot_t4(:,1)
     851              :                      end if
     852              : 
     853          591 :                      if (i1pert==natom+3.or.i1pert==natom+4) then
     854            0 :                        gamma=i3dir
     855            0 :                        do idq=1,n1dq
     856            0 :                          if (i1pert==natom+3) then
     857            0 :                            istr=i1dir
     858              :                          else
     859            0 :                            istr=idq*3+i1dir
     860              :                          endif
     861            0 :                          beta=idx(2*istr-1); delta=idx(2*istr)
     862            0 :                          t5_typeI(:,i2dir,i2pert,beta,delta,gamma)=d3etot_t5(:,idq)
     863              :                        end do
     864              :                      else
     865         1773 :                        t5_typeII(:,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)=d3etot_t5(:,1)
     866              :                      end if
     867              : 
     868              : 
     869          591 :                      if (i1pert<=natom.and.(i2pert==natom+3.or.i2pert==natom+4)) then
     870          324 :                        alpha=i1dir
     871          324 :                        gamma=i3dir
     872          810 :                        do idq=1,n2dq
     873          486 :                          if (i2pert==natom+3) then
     874          162 :                            istr=i2dir
     875              :                          else
     876          324 :                            istr=idq*3+i2dir
     877              :                          endif
     878          486 :                          beta=idx(2*istr-1); delta=idx(2*istr)
     879         1458 :                          tgeom_typeI(:,i1dir,i1pert,beta,delta,gamma)=d3etot_tgeom(:,idq)
     880              : 
     881              :                          !Incorporate here the G=0 contribution of the geometric term
     882          486 :                          ia1=0
     883          486 :                          itypat=0
     884          972 :                          do ii=1,dtset%ntypat
     885          486 :                            ia1=ia1+nattyp(ii)
     886          972 :                            if (atindx(i1pert)<=ia1.and.itypat==0) itypat=ii
     887              :                          end do
     888          486 :                          delad=zero ; if (alpha==delta) delad=one
     889          486 :                          delbd=zero ; if (beta==delta)  delbd=one
     890          486 :                          delag=zero ; if (alpha==gamma) delag=one
     891          486 :                          delbg=zero ; if (beta==gamma)  delbg=one
     892              : 
     893              :                          tgeom_typeI(1,i1dir,i1pert,beta,delta,gamma)= &
     894              :                        & tgeom_typeI(1,i1dir,i1pert,beta,delta,gamma) + &
     895          810 :                        & pi*pi*rhog(1,1)*psps%vlspl(1,2,itypat)*(delag*delbd+delad*delbg)
     896              :                        end do
     897              :                      else
     898          801 :                        tgeom_typeII(:,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)=d3etot_tgeom(:,1)
     899              :                      end if
     900              :                    end if ! .not.just_timdisp
     901              : 
     902          611 :                    if (i3pert==natom+9) then
     903              : 
     904           20 :                       write(message,'(2a,3(a,i2,a,i1))') ch10,'TIMDISP : ',&
     905           40 :                       ' perts : ',i1pert,'.',i1dir,' / ',i2pert,'.',i2dir,' / ',i3pert,'.',i3dir
     906           20 :                       call wrtout(std_out,message,'COLL')
     907           20 :                       call wrtout(ab_out,message,'COLL')
     908              :                      !Perform the Berry curvature part of the time-disperion 3dte calculation
     909              :                      call dfpttd_berrycurv(cg1,cg2,d3etot_td,dtset,&
     910              :                      & mband,mk1mem,mpi_enreg,&
     911           20 :                      & mpw1,nkpt,nspinor,nsppol,npwar1,occ)
     912           20 :                      if (.not.kramers_deg) then
     913              :                        call dfpttd_berrycurv(cg1_mq,cg2_mq,d3etot_td_mq,dtset,&
     914              :                        & mband,mk1mem,mpi_enreg,&
     915            6 :                        & mpw1,nkpt,nspinor,nsppol,npwar1_mq,occ)
     916              :                      end if
     917              : 
     918              :                      !Add the result to the big array
     919              :                      if (kramers_deg) then
     920           14 :                        d3etot(1,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)=zero
     921           14 :                        d3etot(2,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)=-two*d3etot_td(2)
     922              :                      else
     923            6 :                        d3etot(1,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)=-d3etot_td(1)+d3etot_td_mq(1)
     924            6 :                        d3etot(2,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)=-d3etot_td(2)-d3etot_td_mq(2)
     925              :                      end if
     926              : 
     927              :                    end if
     928              : 
     929              :                  end if   ! rfpert
     930              :                end do    ! ir3dir
     931              :              end do     ! ir3pert
     932              : 
     933          242 :              if (finite_q) then
     934            6 :                call hdr1_pq%free()
     935            6 :                call hdr2_pq%free()
     936            6 :                if (.not.kramers_deg) then
     937            6 :                  call hdr1_mq%free()
     938            6 :                  call hdr2_mq%free()
     939              :                end if
     940              :              end if
     941              : 
     942          242 :              ABI_SFREE(vpsp1_i2pertdq)
     943          242 :              ABI_SFREE(xccc3d2dq)
     944          242 :              ABI_SFREE(vxccc1_i2pertdq)
     945          242 :              ABI_FREE(vpsp1_i1pertdq_geom)
     946          242 :              ABI_FREE(vpsp1_i1pertdqdq)
     947          242 :              ABI_FREE(d3etot_t4)
     948          242 :              ABI_FREE(d3etot_tgeom)
     949              : 
     950              :            end if   ! rfpert
     951              :          end do    ! i2dir
     952              :        end do     ! i2pert
     953              : 
     954           55 :        ABI_SFREE(vpsp1_i1pertdq)
     955           55 :        ABI_FREE(d3etot_t5)
     956              : 
     957              :      end if   ! rfpert
     958              :    end do    ! i1dir
     959              :  end do     ! i1pert
     960              : 
     961              : !More memory cleaning
     962           17 :  call gs_hamkq%free()
     963           17 :  ABI_FREE(kpq)
     964           17 :  ABI_FREE(kg1)
     965           17 :  ABI_FREE(npwar1)
     966           17 :  ABI_FREE(npwtot1)
     967           17 :  ABI_FREE(cg1)
     968           17 :  ABI_FREE(cg2)
     969           17 :  ABI_FREE(eigen1)
     970           17 :  ABI_FREE(eigen2)
     971           17 :  ABI_FREE(rho1r1)
     972           17 :  ABI_FREE(rho2r1)
     973           17 :  ABI_FREE(rho1g1)
     974           17 :  ABI_FREE(rho2g1)
     975           17 :  ABI_FREE(nhat1)
     976           17 :  ABI_FREE(pawrhoij_read)
     977           17 :  ABI_SFREE(xccc3d2)
     978              : 
     979           17 :  if (dtset%lw_flexo==1.or.dtset%lw_flexo==2.or.dtset%lw_flexo==4) then
     980            3 :   ABI_FREE(vhart1dqdq)
     981            3 :   ABI_FREE(vpsp1dqdq)
     982            3 :   ABI_FREE(vxc1dqdq)
     983              :  end if
     984              : 
     985           17 :  call ebands_kq%free()
     986           17 :  if (.not.kramers_deg) then
     987            2 :    call ebands_kmq%free()
     988            2 :    ABI_FREE(cg1_mq)
     989            2 :    ABI_FREE(cg2_mq)
     990            2 :    ABI_FREE(eigen1_mq)
     991            2 :    ABI_FREE(eigen2_mq)
     992            2 :    ABI_FREE(kg1_mq)
     993            2 :    ABI_FREE(npwar1_mq)
     994            2 :    ABI_FREE(npwtot1_mq)
     995            2 :    ABI_FREE(kmq)
     996              :  end if
     997              : !Treatment of T4 and T5 terms that have a q-gradient of a rf Hamiltonian
     998              : !they need to be converted to type-II for strain perturbation
     999           17 :  if (d3e_pert2(natom+3)==1.or.d3e_pert2(natom+4)==1) then
    1000            3 :    optgeom=0
    1001            3 :    call dfptlw_typeIproc(blkflg,gprimd,optgeom,mpert,natom,rfpert,rprimd,t4_typeI,t4_typeII)
    1002              :  end if
    1003              : 
    1004           17 :  if (d3e_pert1(natom+3)==1.or.d3e_pert1(natom+4)==1) then
    1005            0 :    optgeom=0
    1006            0 :    call dfptlw_typeIproc(blkflg,gprimd,optgeom,mpert,natom,rfpert,rprimd,t5_typeI,t5_typeII)
    1007              :  end if
    1008              : 
    1009              : !Tgeom has to be converted to type-II
    1010              : !To do it we need to convert the three involve indexes to cartessian. Then,
    1011              : !after type-II conversion the q-gradient index is back converted to reduced.
    1012           55 :  if (any(d3e_pert1(1:natom)==1).and.(d3e_pert2(natom+3)==1.or.d3e_pert2(natom+4)==1)) then
    1013            3 :    optgeom=1
    1014            3 :    call dfptlw_typeIproc(blkflg,gprimd,optgeom,mpert,natom,rfpert,rprimd,tgeom_typeI,tgeom_typeII)
    1015              :  end if
    1016              : 
    1017              : !Incorporate T4, T5 and Tgeom to d3etot
    1018              :   d3etot(:,:,:,:,:,:,:)= d3etot(:,:,:,:,:,:,:) + &
    1019              :                     & t4_typeII(:,:,:,:,:,:,:) + &
    1020              :                     & t5_typeII(:,:,:,:,:,:,:) + &
    1021      6485593 :                  & tgeom_typeII(:,:,:,:,:,:,:)
    1022              : 
    1023              : !Anounce end of spatial-dispersion calculation
    1024           17 :  write(message, '(a,a,a,a)' ) ch10,ch10,&
    1025           34 : &   ' -- Spatial-dispersion 3rd-order derivatives completed -- ',ch10
    1026           17 :  call wrtout(std_out,message,'COLL')
    1027           17 :  call wrtout(ab_out,message,'COLL')
    1028              : 
    1029              : !Deallocations
    1030           17 :  ABI_FREE(t4_typeII)
    1031           17 :  ABI_FREE(t5_typeII)
    1032           17 :  ABI_FREE(tgeom_typeII)
    1033           17 :  ABI_SFREE(t4_typeI)
    1034           17 :  ABI_SFREE(t5_typeI)
    1035           17 :  ABI_SFREE(tgeom_typeI)
    1036              : 
    1037              :  DBG_EXIT("COLL")
    1038              : 
    1039           17 : end subroutine dfptlw_loop
    1040              : !!***
    1041              : 
    1042              : !!****f* ABINIT/m_dfptlw_loop/dfptlw_typeIproc
    1043              : !! NAME
    1044              : !!  dfptlw_typeIproc
    1045              : !!
    1046              : !! FUNCTION
    1047              : !!  Process type-I terms and convert them to type-II in
    1048              : !!  the d3etot mixed (reduced/cartessian) coordinates.
    1049              : !!
    1050              : !! COPYRIGHT
    1051              : !!  Copyright (C) 2022-2026 ABINIT group (MR)
    1052              : !!  This file is distributed under the terms of the
    1053              : !!  GNU General Public License, see ~abinit/COPYING
    1054              : !!  or http://www.gnu.org/copyleft/gpl.txt .
    1055              : !!
    1056              : !! INPUTS
    1057              : !!  blkflg(3,mpert,3,mpert) = flags for each element of the 3DTE
    1058              : !!  gprimd(3,3)=dimensional primitive translations for reciprocal space(bohr^-1)
    1059              : !!  optgeom= if 1 do special treatment for the geometric term
    1060              : !!  mpert =maximum number of ipert
    1061              : !!  natom = number of atoms in unit cell
    1062              : !!  rfpert(3,mpert,3,mpert,3,mpert) = array defining the type of perturbations
    1063              : !!       that have to be computed
    1064              : !!       1   ->   element has to be computed explicitely
    1065              : !!      -1   ->   use symmetry operations to obtain the corresponding element
    1066              : !!  rprimd(3,3)=dimensional primitive translations (bohr)
    1067              : !!  t_typeI(2,3,mpert,3,3,3)= Input type-I tensor
    1068              : !!
    1069              : !! OUTPUT
    1070              : !!  t_typeII(2,3,mpert,3,mpert,3,mpert)= type-II tensor converted to the mixed
    1071              : !!       coordinates.
    1072              : !!
    1073              : !! SOURCE
    1074              : 
    1075           12 : subroutine dfptlw_typeIproc(blkflg,gprimd,optgeom,mpert,natom,rfpert,rprimd,t_typeI,&
    1076            6 :  & t_typeII)
    1077              : 
    1078              :  use defs_basis
    1079              :  use m_errors
    1080              :  use m_profiling_abi
    1081              :  use m_dynmat,      only : cart39
    1082              : 
    1083              : !Arguments ------------------------------------
    1084              : !scalars
    1085              :  integer,intent(in) :: mpert,natom,optgeom
    1086              : !arrays
    1087              :  integer,intent(in) :: blkflg(3,mpert,3,mpert,3,mpert)
    1088              :  integer,intent(in) :: rfpert(3,mpert,3,mpert,3,mpert)
    1089              :  real(dp),intent(in) :: gprimd(3,3),rprimd(3,3)
    1090              :  real(dp),intent(inout) :: t_typeI(2,3,mpert,3,3,3)
    1091              :  real(dp),intent(inout) :: t_typeII(2,3,mpert,3,mpert,3,mpert)
    1092              : 
    1093              : !Local variables-------------------------------
    1094              : !scalar
    1095              :  integer :: beta,delta,gamma,ii
    1096              :  integer :: i1dir,i1pert,i2dir,i2pert,i3dir,i3pert,istr
    1097              :  real(dp) :: fac
    1098              : !arrays
    1099              :  integer,save :: idx(18)=(/1,1,2,2,3,3,3,2,3,1,2,1,2,3,1,3,1,2/)
    1100              :  integer :: flg1(3),flg2(3)
    1101              :  real(dp) :: vec1(3),vec2(3)
    1102              :  real(dp) :: rprimd_t(3,3),gprimd_t(3,3)
    1103              : 
    1104              : ! *************************************************************************
    1105              : 
    1106              :  DBG_ENTER("COLL")
    1107              : 
    1108            6 :  if (optgeom==1) then
    1109              :    !Transform the metric perturbation direction
    1110              :    !(treat it as an atomic displacement)
    1111           12 :    flg1(:)=1
    1112            9 :    do i1pert=1,natom
    1113           27 :      do i1dir=1,3
    1114           78 :        do gamma=1,3
    1115          180 :          do ii=1,2
    1116          486 :            do delta=1,3
    1117         1296 :              do beta=1,3
    1118         1296 :                vec1(beta)=t_typeI(ii,i1dir,i1pert,beta,delta,gamma)
    1119              :              end do
    1120          324 :              call cart39(flg1,flg2,gprimd,i1pert,natom,rprimd,vec1,vec2)
    1121         1404 :              do beta=1,3
    1122         1296 :                t_typeI(ii,i1dir,i1pert,beta,delta,gamma)=vec2(beta)
    1123              :              end do
    1124              :            end do
    1125              :          end do
    1126              :        end do
    1127              :      end do
    1128              :    end do
    1129              : 
    1130              :    !Transform the second q-gradient direction
    1131              :    !(treat it as an electric field)
    1132            9 :    do i1pert=1,natom
    1133           27 :      do i1dir=1,3
    1134           78 :        do gamma=1,3
    1135          180 :          do ii=1,2
    1136          486 :            do beta=1,3
    1137         1296 :              do delta=1,3
    1138         1296 :                vec1(delta)=t_typeI(ii,i1dir,i1pert,beta,delta,gamma)
    1139              :              end do
    1140          324 :              call cart39(flg1,flg2,gprimd,natom+2,natom,rprimd,vec1,vec2)
    1141         1404 :              do delta=1,3
    1142         1296 :                t_typeI(ii,i1dir,i1pert,beta,delta,gamma)=vec2(delta)
    1143              :              end do
    1144              :            end do
    1145              :          end do
    1146              :        end do
    1147              :      end do
    1148              :    end do
    1149              : 
    1150              :    !Transform the first q-gradient direction
    1151              :    !(treat it as an electric field)
    1152            9 :    do i1pert=1,natom
    1153           27 :      do i1dir=1,3
    1154           60 :        do ii=1,2
    1155          162 :          do beta=1,3
    1156          468 :            do delta=1,3
    1157         1296 :              do gamma=1,3
    1158         1296 :                vec1(gamma)=t_typeI(ii,i1dir,i1pert,beta,delta,gamma)
    1159              :              end do
    1160          324 :              call cart39(flg1,flg2,gprimd,natom+2,natom,rprimd,vec1,vec2)
    1161         1404 :              do gamma=1,3
    1162         1296 :                t_typeI(ii,i1dir,i1pert,beta,delta,gamma)=vec2(gamma)
    1163              :              end do
    1164              :            end do
    1165              :          end do
    1166              :        end do
    1167              :      end do
    1168              :    end do
    1169              : 
    1170              :  end if
    1171              : 
    1172            6 :  fac=two_pi ** 2
    1173            6 :  i3pert= natom+8
    1174           78 :  rprimd_t=transpose(rprimd)
    1175           78 :  gprimd_t=transpose(gprimd)
    1176           66 :  do i1pert = 1, mpert
    1177          246 :    do i1dir = 1, 3
    1178       223440 :      if ((maxval(rfpert(i1dir,i1pert,:,:,:,:))==1)) then
    1179          162 :        do i2pert = natom+3, natom+4
    1180          486 :          do i2dir = 1, 3
    1181          324 :            istr=(i2pert-natom-3)*3+i2dir
    1182          324 :            beta=idx(2*istr-1); delta=idx(2*istr)
    1183         1080 :            do ii=1,2
    1184              : 
    1185              :              !Transform into type-II
    1186         2592 :              do i3dir=1,3
    1187         1944 :                gamma=i3dir
    1188              :                t_typeII(ii,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)= &
    1189              :              & t_typeI(ii,i1dir,i1pert,beta,delta,gamma) + &
    1190              :              & t_typeI(ii,i1dir,i1pert,delta,gamma,beta) - &
    1191         2592 :              & t_typeI(ii,i1dir,i1pert,gamma,beta,delta)
    1192              :              end do ! i3dir
    1193              : 
    1194              :              !Transform i3dir into reduced coordinates
    1195         2592 :              do i3dir=1,3
    1196         1944 :                vec1(i3dir)=t_typeII(ii,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)
    1197         2592 :                flg1(i3dir)=blkflg(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)
    1198              :              end do
    1199          648 :              call cart39(flg1,flg2,rprimd_t,natom+2,natom,gprimd_t,vec1,vec2)
    1200         2916 :              do i3dir=1,3
    1201         2592 :                t_typeII(ii,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)=vec2(i3dir)*fac
    1202              :              end do
    1203              : 
    1204              :            end do ! ii
    1205              :          end do ! i2dir
    1206              :        end do ! i2pert
    1207              :      end if ! rfpert
    1208              :    end do ! i1dir
    1209              :  end do ! i1pert
    1210              : 
    1211              :  DBG_EXIT("COLL")
    1212              : 
    1213            6 : end subroutine dfptlw_typeIproc
    1214              : !!***
    1215              : 
    1216              : !!****f* ABINIT/m_dfptlw_loop/read_1eig
    1217              : !! NAME
    1218              : !!  read_1eig
    1219              : !!
    1220              : !! FUNCTION
    1221              : !!
    1222              : !!  Reads all the first-order energies from a given _1WF file.
    1223              : !!  Data is read by the master and broadcasted.
    1224              : !!
    1225              : !! COPYRIGHT
    1226              : !!  Copyright (C) 2022-2026 ABINIT group (MR)
    1227              : !!  This file is distributed under the terms of the
    1228              : !!  GNU General Public License, see ~abinit/COPYING
    1229              : !!  or http://www.gnu.org/copyleft/gpl.txt .
    1230              : !!
    1231              : !! INPUTS
    1232              : !! formeig option (format of the eigenvalues and occupations) :
    1233              : !!   0 => ground-state format
    1234              : !!   1 => respfn format
    1235              : !!  mband=maximum number of bands
    1236              : !!  nkpt= number of k points
    1237              : !!  nsppol=1 for unpolarized, 2 for spin-polarized
    1238              : !!  wffnm=name (character data) of file for input wavefunctions.
    1239              : !!
    1240              : !! OUTPUT
    1241              : !!  eigen(2*mband*mband*nkpt*nsppol)=matrix of eigenvalues
    1242              : !!
    1243              : !! SOURCE
    1244              : 
    1245          265 : subroutine read_1eig(eigen,formeig,mband,nkpt,nsppol,wffnm)
    1246              : 
    1247              : !Arguments ------------------------------------
    1248              : !scalars
    1249              :  integer,intent(in) :: formeig,mband,nkpt,nsppol
    1250              :  character(len=*),intent(inout) :: wffnm
    1251              : !arrays
    1252              :  real(dp),intent(out) :: eigen((2*mband)**formeig*mband*nkpt*nsppol)
    1253              : 
    1254              : !Local variables-------------------------------
    1255              : !scalar
    1256              :  integer :: bd2tot,comm,ierr,ik_bz,iomode,isppol,master,my_rank
    1257         1060 :  type(wfk_t) :: Wfk1
    1258          265 :  type(hdr_type) :: hdr1
    1259              :  character(len=500) :: msg
    1260              : !arrays
    1261          265 :  real(dp),allocatable :: eig_buffer(:)
    1262              : 
    1263              : ! *************************************************************************
    1264              : 
    1265              : DBG_ENTER("COLL")
    1266              : 
    1267          265 :  comm = xmpi_world
    1268          265 :  master = 0
    1269          265 :  my_rank = xmpi_comm_rank(comm)
    1270              : 
    1271              :  ! Master opens the 1WF file
    1272          265 :  if (my_rank == master) then
    1273          265 :    iomode = iomode_from_fname(wffnm)
    1274              : 
    1275              :    !Check that atdis file exists and open it
    1276          265 :    if (.not. file_exists(wffnm)) then
    1277              :      ! Trick needed to run Abinit test suite in netcdf mode.
    1278          265 :      if (file_exists(nctk_ncify(wffnm))) then
    1279          265 :        write(msg,"(3a)")"- File: ",trim(wffnm),&
    1280          530 :        " does not exist but found netcdf file with similar name."
    1281          265 :        call wrtout(std_out,msg,'COLL')
    1282          530 :        wffnm = nctk_ncify(wffnm)
    1283              :      end if
    1284          265 :      if (.not. file_exists(wffnm)) then
    1285            0 :        ABI_ERROR('Missing file: '//TRIM(wffnm))
    1286              :      end if
    1287              :    end if
    1288          265 :    write(msg,'(a,a)')'-open 1wf file :',trim(wffnm)
    1289          265 :    call wrtout(std_out,msg,'COLL')
    1290              : 
    1291          265 :    call wfk1%open_read(wffnm, formeig, iomode, get_unit(), xmpi_comm_self, Hdr_out=hdr1)
    1292              :  end if
    1293              : 
    1294              :  ! Master Broadcasts the header to all procs in comm
    1295          265 :  call hdr1%bcast(master, my_rank, comm)
    1296              : 
    1297              :  !Allocate buffer for MPI communicatio with max dimensions.
    1298          795 :  ABI_MALLOC(eig_buffer, ((2*mband)**formeig*mband*nsppol))
    1299              : 
    1300          265 :  bd2tot = 0
    1301          530 :  do isppol=1,nsppol
    1302        30658 :    do ik_bz=1,hdr1%nkpt
    1303              : 
    1304              :      !Master reads and broadcasts
    1305        30128 :      if (my_rank == master) then
    1306        90384 :        call Wfk1%read_band_block([1,mband], ik_bz, isppol, xmpio_single, eig_k=eig_buffer)
    1307              :      end if
    1308              : 
    1309        30128 :      call xmpi_bcast(eig_buffer, master, comm, ierr)
    1310              : 
    1311      1049008 :      eigen(1+bd2tot:2*mband**2+bd2tot)=eig_buffer(:)
    1312              : 
    1313              :      !Keep track of total number of bands
    1314        60521 :      bd2tot = bd2tot + 2*mband**2
    1315              :    end do
    1316              :  end do
    1317              : 
    1318          265 :  if (my_rank == master) call Wfk1%close()
    1319          265 :  call hdr1%free()
    1320              : 
    1321          265 :  ABI_FREE(eig_buffer)
    1322              : 
    1323              :  DBG_EXIT("COLL")
    1324              : 
    1325          536 : end subroutine read_1eig
    1326              : !!***
    1327              : 
    1328              : end module m_dfptlw_loop
    1329              : !!***
        

Generated by: LCOV version 2.3-1