LCOV - code coverage report
Current view: top level - src/95_drive - m_longwave.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 93.2 % 555 517
Test Date: 2026-11-09 13:21:34 Functions: 100.0 % 2 2
Branches: 52.5 % 2016 1059

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_longwave
       2                 :             : !! NAME
       3                 :             : !!  m_longwave
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!  DFPT calculation of spatial and time dispersion properties
       7                 :             : !!
       8                 :             : !! COPYRIGHT
       9                 :             : !!  Copyright (C) 2019-2026 ABINIT group (MR, MS)
      10                 :             : !!  This file is distributed under the terms of the
      11                 :             : !!  GNU General Public License, see ~abinit/COPYING
      12                 :             : !!  or http://www.gnu.org/copyleft/gpl.txt .
      13                 :             : !!
      14                 :             : !! NOTES
      15                 :             : !!
      16                 :             : !! SOURCE
      17                 :             : 
      18                 :             : #if defined HAVE_CONFIG_H
      19                 :             : #include "config.h"
      20                 :             : #endif
      21                 :             : 
      22                 :             : #include "abi_common.h"
      23                 :             : 
      24                 :             : module m_longwave
      25                 :             : 
      26                 :             :  use defs_basis
      27                 :             :  use m_errors
      28                 :             :  use m_xmpi
      29                 :             :  use defs_datatypes
      30                 :             :  use defs_abitypes, only : MPI_type
      31                 :             :  use defs_wvltypes
      32                 :             :  use m_dtset
      33                 :             :  use m_dtfil
      34                 :             :  use m_xcdata
      35                 :             :  use m_hdr
      36                 :             :  use m_ebands
      37                 :             :  use m_wffile
      38                 :             : 
      39                 :             :  use m_pspini,      only : pspini
      40                 :             :  use m_common,      only : setup1
      41                 :             :  use m_pawfgr,      only : pawfgr_type, pawfgr_init, pawfgr_destroy
      42                 :             :  use m_pawrhoij,    only : pawrhoij_type
      43                 :             :  use m_paw_dmft,    only : paw_dmft_type
      44                 :             :  use m_pawrad,      only : pawrad_type
      45                 :             :  use m_pawtab,      only : pawtab_type
      46                 :             :  use m_drivexc,     only : check_kxc
      47                 :             :  use m_rhotoxc,     only : rhotoxc
      48                 :             :  use m_ioarr,       only : read_rhor
      49                 :             :  use m_matrix,      only : matr3inv
      50                 :             :  use m_symtk,       only : symmetrize_xred
      51                 :             :  use m_kg,          only : kpgio,getcut,getph
      52                 :             :  use m_inwffil,     only : inwffil
      53                 :             :  use m_spacepar,    only : setsym
      54                 :             :  use m_mkrho,       only : mkrho
      55                 :             :  use m_fft,         only : fourdp
      56                 :             :  use m_ddb,         only : ddb_type,lwcart
      57                 :             :  use m_ddb_hdr,     only : ddb_hdr_type
      58                 :             :  use m_mkcore,      only : mkcore
      59                 :             :  use m_dfptlw_loop, only : dfptlw_loop
      60                 :             :  use m_dfptlw_nv,   only : dfptlw_nv
      61                 :             :  use m_dfptlw_pert, only : preca_ffnl
      62                 :             :  use m_initylmg,    only : initylmg
      63                 :             :  use m_geometry,    only : symredcart, d3lwsym, sylwtens
      64                 :             :  use m_atm2fft,     only : atm2fft
      65                 :             : 
      66                 :             :  implicit none
      67                 :             : 
      68                 :             :  private
      69                 :             : !!***
      70                 :             : 
      71                 :             :  public :: longwave
      72                 :             : !!***
      73                 :             : 
      74                 :             : ! *************************************************************************
      75                 :             : 
      76                 :             : contains
      77                 :             : !!***
      78                 :             : 
      79                 :             : !!****f* ABINIT/longwave
      80                 :             : !! NAME
      81                 :             : !!  longwave
      82                 :             : !!
      83                 :             : !! FUNCTION
      84                 :             : !! Primary routine for conducting DFPT calculations of dispersion properties
      85                 :             : !!
      86                 :             : !! INPUTS
      87                 :             : !!  codvsn = code version
      88                 :             : !!  dtfil <type(datafiles_type)> = variables related to files
      89                 :             : !!  dtset <type(dataset_type)> = all input variables for this dataset
      90                 :             : !!  etotal = new total energy (no meaning at output)
      91                 :             : !!  mpi_enreg=information about MPI pnarallelization
      92                 :             : !!  occ(mband*nkpt*nsppol) = occupation number for each band and k
      93                 :             : !!  xred(3,natom) = reduced atomic coordinates
      94                 :             : !!
      95                 :             : !! OUTPUT
      96                 :             : !!  npwtot(nkpt) = total number of plane waves at each k point
      97                 :             : !!
      98                 :             : !! SIDE EFFECTS
      99                 :             : !!  pawrad(ntypat*usepaw) <type(pawrad_type)>=paw radial mesh and related data
     100                 :             : !!  pawtab(ntypat*usepaw) <type(pawtab_type)>=paw tabulated starting data
     101                 :             : !!  psps <type(pseudopotential_type)> = variables related to pseudopotentials
     102                 :             : !!
     103                 :             : !! SOURCE
     104                 :             : 
     105                 :          17 : subroutine longwave(codvsn,dtfil,dtset,etotal,mpi_enreg,npwtot,occ,&
     106                 :          17 :                    pawrad,pawtab,psps,xred)
     107                 :             : 
     108                 :             : #ifdef FC_INTEL
     109                 :             : !DEC$ NOOPTIMIZE
     110                 :             : #endif
     111                 :             : 
     112                 :             : !Arguments ------------------------------------
     113                 :             :  !scalars
     114                 :             :  real(dp),intent(inout) :: etotal
     115                 :             :  character(len=8),intent(in) :: codvsn
     116                 :             :  type(MPI_type),intent(inout) :: mpi_enreg
     117                 :             :  type(datafiles_type),intent(in) :: dtfil
     118                 :             :  type(dataset_type),intent(inout) :: dtset
     119                 :             :  type(pseudopotential_type),intent(inout) :: psps
     120                 :             :  !arrays
     121                 :             :  integer,intent(out) :: npwtot(dtset%nkpt)
     122                 :             :  real(dp),intent(inout) :: occ(dtset%mband*dtset%nkpt*dtset%nsppol),xred(3,dtset%natom)
     123                 :             :  type(pawrad_type),intent(inout) :: pawrad(psps%ntypat*psps%usepaw)
     124                 :             :  type(pawtab_type),intent(inout) :: pawtab(psps%ntypat*psps%usepaw)
     125                 :             : 
     126                 :             : !Local variables-------------------------------
     127                 :             :  !scalars
     128                 :             :  integer,parameter :: cplex1=1,formeig=0,response=1
     129                 :             :  integer :: ask_accurate,bantot,dimffnl,dimffnl_i
     130                 :             :  integer :: gscase,iatom,ierr,indx,ireadwf0,iscf_eff,itypat
     131                 :             :  integer :: ider,idir0,idir
     132                 :             :  integer :: i1dir,i1pert,i2dir,ii,i2pert,i3dir,i3pert
     133                 :             :  integer :: me,mcg,mgfftf,natom,nfftf,nfftot,nfftotf,nhatdim,nhatgrdim
     134                 :             : ! integer :: isym
     135                 :             :  integer :: mpert,my_natom,n1,nkxc,nk3xc,ntypat,n3xccc,nylmgr
     136                 :             :  integer :: optatm,optdyfr,opteltfr,optgr,optstr,optv,optn,optn2
     137                 :             :  integer :: option,optorth,psp_gencond,rdwrpaw,spaceworld,timrev,tim_mkrho
     138                 :             :  integer :: usexcnhat,useylmgr
     139                 :             :  real(dp) :: bigexc,bigsxc,boxcut,ecore,ecutdg_eff,ecut_eff,etot
     140                 :             :  real(dp) :: fermie,fermih,gsqcut,gsqcut_eff,gsqcutc_eff,residm
     141                 :             :  real(dp) :: ucvol,vxcavg
     142                 :             :  logical :: non_magnetic_xc,just_timdisp
     143                 :             : ! logical :: has_strain
     144                 :             :  character(len=500) :: msg
     145                 :          17 :  type(ebands_t) :: bstruct
     146   [ +  +  +  +  :         884 :  type(ddb_hdr_type) :: ddb_hdr
          +  +  +  +  +  
          +  +  +  +  +  
             +  +  +  + ]
     147                 :          17 :  type(ddb_type) :: ddb
     148                 :          17 :  type(paw_dmft_type) :: paw_dmft
     149                 :             :  type(pawfgr_type) :: pawfgr
     150                 :          17 :  type(hdr_type) :: hdr,hdr_den
     151                 :             :  type(xcdata_type) :: xcdata
     152                 :          17 :  type(wvl_data) :: wvl
     153                 :             :  type(wffile_type) :: wffgs,wfftgs
     154                 :             :  !arrays
     155                 :             :  integer :: d3e_dir1(3),d3e_dir2(3),d3e_dir3(3)
     156                 :             :  integer :: ngfft(18),ngfftf(18),perm(6)
     157                 :             :  real(dp) :: dummy6(6),other_dummy6(6),gmet(3,3),gmet_for_kg(3,3),gprimd(3,3),gprimd_for_kg(3,3)
     158                 :             :  real(dp) :: rmet(3,3),rprimd(3,3),rprimd_for_kg(3,3)
     159                 :             :  real(dp) :: dum_gauss(0),dum_dyfrv(0),dum_eltfrxc(0)
     160                 :             :  real(dp) :: dum_grn(0),dum_grv(0),dum_rhog(0),dum_vg(0)
     161                 :          17 :  integer,allocatable :: atindx(:),atindx1(:)
     162                 :          17 :  integer,allocatable :: blkflg(:,:,:,:,:,:),blkflg_car(:,:,:,:,:,:)
     163                 :          17 :  integer,allocatable :: d3e_pert1(:),d3e_pert2(:),d3e_pert3(:)
     164                 :          17 :  integer,allocatable :: indsym(:,:,:),irrzon(:,:,:),kg(:,:)
     165                 :          17 :  integer,allocatable :: nattyp(:),npwarr(:),symrec(:,:,:)
     166                 :          17 :  integer,allocatable :: rfpert(:,:,:,:,:,:)
     167                 :          17 :  real(dp),allocatable :: cg(:,:)
     168                 :          17 :  real(dp),allocatable :: d3etot(:,:,:,:,:,:,:),d3etot_car(:,:,:,:,:,:,:)
     169                 :          17 :  real(dp),allocatable :: d3etot_nv(:,:,:,:,:,:,:),doccde(:)
     170                 :          17 :  real(dp),allocatable :: eigen0(:),ffnl(:,:,:,:,:),ffnl_i(:,:,:,:,:)
     171                 :          17 :  real(dp),allocatable :: grxc(:,:),kxc(:,:),vxc(:,:)
     172                 :          17 :  real(dp),allocatable :: ncorespl(:,:,:),nhat(:,:),nhatgr(:,:,:)
     173                 :          17 :  real(dp),allocatable :: phnons(:,:,:),ph1d(:,:),rhog(:,:),rhor(:,:),dummy_dyfrx2(:,:,:)
     174                 :             : ! real(dp),allocatable :: symrel_cart(:,:,:)
     175                 :          17 :  real(dp),allocatable :: dummy_vpsp(:),work(:),xccc3d(:)
     176                 :          17 :  real(dp),allocatable :: ylm(:,:),ylmgr(:,:,:)
     177                 :          17 :  type(pawrhoij_type),allocatable :: pawrhoij(:),pawrhoij_read(:)
     178                 :             : ! *************************************************************************
     179                 :             : 
     180                 :             :  DBG_ENTER("COLL")
     181                 :             : 
     182                 :             : !Just time dispersion calculation
     183                 :          17 :  just_timdisp=.false.
     184                 :             :  if (dtset%lw_flexo==0.and.dtset%lw_qdrpl==0.and.&
     185   [ +  +  +  +  :          17 : &  dtset%lw_natopt==0.and.dtset%timdisp==1) just_timdisp=.true.
                   +  - ]
     186                 :             : 
     187                 :             : !Not valid for PAW
     188         [ -  + ]:          17 :  if (psps%usepaw==1) then
     189                 :           0 :    msg='This routine cannot be used for PAW!'
     190                 :           0 :    ABI_BUG(msg)
     191                 :             :  end if
     192                 :             : 
     193                 :             : !Not valid for finite wave-vector perturbations
     194   [ +  +  +  +  :          68 :  if (.not.just_timdisp.and.sqrt(sum(dtset%qptn**2))>tol8) then
                   -  + ]
     195                 :           0 :    msg='This routine can only be used at q /= 0 for time dispersion calculation '
     196                 :           0 :    ABI_BUG(msg)
     197                 :             :  end if
     198                 :             : 
     199                 :             : !Only usable with spherical harmonics
     200   [ +  +  -  +  :          17 :  if (dtset%useylm/=1.and.(.not.just_timdisp.and.dtset%lw_qdrpl/=0.or.dtset%lw_flexo/=0)) then
             -  -  -  + ]
     201                 :           0 :    msg='This routine can only be used with useylm/=1 for the spatial dispersion given by lw_natopt=1'
     202                 :           0 :    ABI_BUG(msg)
     203                 :             :  end if
     204                 :             : 
     205                 :             : !Not valid for spin-dependent calculations
     206   [ +  +  +  -  :          17 :  if (.not.just_timdisp.and.(dtset%nspinor/=1.or.dtset%nsppol/=1.or.dtset%nspden/=1)) then
             +  -  -  + ]
     207                 :           0 :    msg='This routine cannot be used for spin-dependent calculations of spatial dispersion'
     208                 :           0 :    ABI_BUG(msg)
     209                 :             :  end if
     210                 :             : 
     211                 :             : !Not usable with core electron density corrections and flexo
     212   [ +  +  +  +  :          17 :  if (.not.just_timdisp.and.psps%n1xccc/=0.and.dtset%lw_flexo/=0) then
                   -  + ]
     213                 :           0 :    msg='This routine cannot be used to calculate flexoelectric properties with n1xccc/=0'
     214                 :           0 :    ABI_BUG(msg)
     215                 :             :  end if
     216                 :             : 
     217                 :             : !Only usable for insulators
     218                 :             :  if(0>dtset%occopt .and. dtset%occopt>2)then
     219                 :             :    msg='This routine cannot be used with metallic occupations'
     220                 :             :  end if
     221                 :             : 
     222                 :             : !Define some data
     223                 :          17 :  ntypat=psps%ntypat
     224                 :          17 :  natom=dtset%natom
     225                 :          17 :  timrev=1
     226                 :             : 
     227                 :             : !Init spaceworld
     228                 :          17 :  spaceworld=mpi_enreg%comm_cell
     229                 :          17 :  my_natom=mpi_enreg%my_natom
     230                 :          17 :  me = xmpi_comm_rank(spaceworld)
     231                 :             : 
     232                 :             : !Define FFT grid(s) sizes (be careful !)
     233                 :             : !See NOTES in the comments at the beginning of this file.
     234                 :          17 :  call pawfgr_init(pawfgr,dtset,mgfftf,nfftf,ecut_eff,ecutdg_eff,ngfft,ngfftf)
     235         [ +  + ]:          68 :  nfftot=product(ngfft(1:3))
     236                 :             :  nfftotf=product(ngfftf(1:3))
     237                 :             : 
     238                 :             : !Set up for iterations
     239                 :             :  call setup1(dtset%acell_orig(1:3,1),bantot,dtset,&
     240                 :             : & ecutdg_eff,ecut_eff,gmet,gprimd,gsqcut_eff,gsqcutc_eff,&
     241                 :             : & ngfftf,ngfft,dtset%nkpt,dtset%nsppol,&
     242   [ -  +  -  -  :          17 : & response,rmet,dtset%rprim_orig(1:3,1:3,1),rprimd,ucvol,psps%usepaw)
                   -  - ]
     243                 :             : 
     244                 :             : !Define the set of admitted perturbations taking into account
     245                 :             : !the possible permutations
     246                 :             : !  -> natom+8 refers to ddq perturbation (spatial dispersion)
     247                 :             : !  -> natom+9 refers to ddw perturbation (time dispersion)
     248         [ +  + ]:          17 :  if (dtset%timdisp==0) then
     249                 :          11 :    mpert=natom+8
     250                 :             :  else
     251                 :           6 :    mpert=natom+9
     252   [ +  +  +  + ]:           6 :    if (dtset%d3e_pert1_magn==2.or.dtset%d3e_pert2_magn==2) mpert=2*dtset%natom+11
     253                 :             :  end if
     254   [ -  +  +  -  :         119 :  ABI_MALLOC(blkflg,(3,mpert,3,mpert,3,mpert))
          +  -  -  +  +  
          -  +  -  -  +  
          +  -  +  -  +  
             -  -  +  -  
                      + ]
     255   [ -  +  +  -  :         119 :  ABI_MALLOC(d3etot,(2,3,mpert,3,mpert,3,mpert))
          +  -  -  +  +  
          -  +  -  -  +  
          +  -  +  -  +  
             -  -  +  -  
                      + ]
     256   [ -  +  +  -  :          68 :  ABI_MALLOC(d3etot_nv,(2,3,mpert,3,mpert,3,mpert))
          -  +  +  -  -  
          +  +  -  -  +  
                   -  + ]
     257   [ -  +  +  -  :          68 :  ABI_MALLOC(rfpert,(3,mpert,3,mpert,3,mpert))
          -  +  +  -  -  
          +  +  -  -  +  
                   -  + ]
     258   [ -  +  +  -  :          51 :  ABI_MALLOC(d3e_pert1,(mpert))
          +  -  +  -  -  
                +  -  + ]
     259   [ -  +  +  -  :          34 :  ABI_MALLOC(d3e_pert2,(mpert))
             -  +  -  + ]
     260   [ -  +  +  -  :          34 :  ABI_MALLOC(d3e_pert3,(mpert))
             -  +  -  + ]
     261   [ +  +  +  +  :     2623081 :  blkflg(:,:,:,:,:,:) = 0
          +  +  +  +  +  
                +  +  + ]
     262   [ +  +  +  +  :     6485593 :  d3etot(:,:,:,:,:,:,:) = zero
          +  +  +  +  +  
             +  +  +  +  
                      + ]
     263   [ +  +  +  +  :     6485593 :  d3etot_nv(:,:,:,:,:,:,:) = zero
          +  +  +  +  +  
             +  +  +  +  
                      + ]
     264   [ +  +  +  +  :     2623081 :  rfpert(:,:,:,:,:,:) = 0
          +  +  +  +  +  
                +  +  + ]
     265   [ +  +  +  +  :         743 :  d3e_pert1(:) = 0 ; d3e_pert2(:) = 0 ; d3e_pert3(:) = 0
                   +  + ]
     266                 :             : 
     267                 :             : !Spatial-dispersion perturbations
     268         [ +  + ]:          17 :  if (.not.just_timdisp) d3e_pert3(natom+8)=1
     269                 :             : 
     270         [ +  + ]:          17 :  if (dtset%lw_qdrpl==1) then
     271                 :           7 :    d3e_pert1(natom+2)=1
     272         [ +  + ]:          24 :    d3e_pert2(1:natom)=1
     273                 :             :  end if
     274                 :             : 
     275         [ +  + ]:          17 :  if (dtset%lw_flexo==2.or.dtset%lw_flexo==1) then
     276                 :           3 :    d3e_pert1(natom+2)=1
     277         [ +  + ]:           9 :    d3e_pert2(natom+3:natom+4)=1
     278                 :             :  end if
     279                 :             : 
     280         [ +  + ]:          17 :  if (dtset%lw_flexo==3.or.dtset%lw_flexo==1) then
     281         [ +  + ]:           9 :    d3e_pert1(natom+2)=1 ; d3e_pert1(1:natom)=1
     282         [ +  + ]:           9 :    d3e_pert2(1:natom)=1
     283                 :             :  end if
     284                 :             : 
     285         [ +  + ]:          17 :  if (dtset%lw_flexo==4.or.dtset%lw_flexo==1) then
     286         [ +  + ]:           9 :    d3e_pert1(1:natom)=1
     287         [ +  + ]:           9 :    d3e_pert2(natom+3:natom+4)=1
     288                 :             :  end if
     289                 :             : 
     290         [ +  + ]:          17 :  if (dtset%lw_natopt==1) then
     291                 :           1 :    d3e_pert1(natom+2)=1
     292                 :           1 :    d3e_pert2(natom+2)=1
     293                 :             :  end if
     294                 :             : 
     295                 :          17 :  perm(:)=0
     296         [ +  + ]:         259 :  do i1pert = 1, mpert
     297         [ +  + ]:        4183 :    do i2pert = 1, mpert
     298         [ +  + ]:       75694 :      do i3pert = 1, mpert
     299                 :       71528 :        perm(1)=d3e_pert1(i1pert)*d3e_pert2(i2pert)*d3e_pert3(i3pert)
     300                 :             : !       perm(2)=d3e_pert1(i1pert)*d3e_pert2(i3pert)*d3e_pert3(i2pert)
     301                 :             : !       perm(3)=d3e_pert1(i2pert)*d3e_pert2(i1pert)*d3e_pert3(i3pert)
     302                 :             : !       perm(4)=d3e_pert1(i2pert)*d3e_pert2(i3pert)*d3e_pert3(i1pert)
     303                 :             : !       perm(5)=d3e_pert1(i3pert)*d3e_pert2(i2pert)*d3e_pert3(i1pert)
     304                 :             : !       perm(6)=d3e_pert1(i3pert)*d3e_pert2(i1pert)*d3e_pert3(i2pert)
     305   [ +  +  +  +  :      506726 :        if ( sum(perm(:)) > 0 ) rfpert(:,i1pert,:,i2pert,:,i3pert)=1
          +  +  +  +  +  
                      + ]
     306                 :             :      end do
     307                 :             :    end do
     308                 :             :  end do
     309                 :             : 
     310                 :             : !Time-dispersion perturbations
     311                 :             : ! d3e_pert1(:) = 0 ; d3e_pert2(:) = 0 ; d3e_pert3(:) = 0
     312                 :             : ! d3e_dir1(:) = 0 ; d3e_dir2(:) = 0 ; d3e_dir3(:) = 0
     313         [ +  + ]:          17 :  if (dtset%timdisp==1) then
     314                 :           6 :    d3e_pert3(natom+9)=1
     315                 :           6 :    d3e_dir3(1)=1
     316                 :           6 :    d3e_dir3(2)=0
     317                 :           6 :    d3e_dir3(3)=0
     318                 :             : 
     319                 :             :    !Atomic displacements
     320   [ +  +  +  + ]:          10 :    if (dtset%d3e_pert1_phon==1) d3e_pert1(dtset%d3e_pert1_atpol(1):dtset%d3e_pert1_atpol(2))=1
     321   [ +  +  +  + ]:          10 :    if (dtset%d3e_pert2_phon==1) d3e_pert2(dtset%d3e_pert2_atpol(1):dtset%d3e_pert2_atpol(2))=1
     322                 :             : 
     323                 :             :    !Electric fields
     324         [ +  + ]:           6 :    if (dtset%d3e_pert1_elfd/=0) d3e_pert1(natom+2)=1
     325         [ +  + ]:           6 :    if (dtset%d3e_pert2_elfd/=0) d3e_pert2(natom+2)=1
     326                 :             : 
     327                 :             :    !Macroscopic hspinfields
     328         [ +  + ]:           6 :    if (dtset%d3e_pert1_magn==1) d3e_pert1(natom+5)=1
     329         [ +  + ]:           6 :    if (dtset%d3e_pert2_magn==1) d3e_pert2(natom+5)=1
     330                 :             : 
     331                 :             :    !Local hspinfields
     332   [ +  +  +  + ]:           9 :    if (dtset%d3e_pert1_magn==2) d3e_pert1(natom+11+dtset%d3e_pert1_magat(1):natom+11+dtset%d3e_pert1_magat(2))=1
     333   [ +  +  +  + ]:           9 :    if (dtset%d3e_pert2_magn==2) d3e_pert2(natom+11+dtset%d3e_pert2_magat(1):natom+11+dtset%d3e_pert2_magat(2))=1
     334                 :             : 
     335                 :           6 :    perm(:)=0
     336         [ +  + ]:         128 :    do i1pert = 1, mpert
     337         [ +  + ]:         488 :      d3e_dir1(:)=dtset%d3e_pert1_dir(:)
     338   [ +  +  +  - ]:         122 :      if (i1pert>natom+11.and.i1pert<=2*natom+11) &
     339         [ +  + ]:          96 :    & d3e_dir1(:)=dtset%d3e_pert1_magdir(:)
     340         [ +  + ]:         494 :      do i1dir = 1, 3
     341         [ +  + ]:        8186 :        do i2pert = 1, mpert
     342         [ +  + ]:       30792 :          d3e_dir2(:)=dtset%d3e_pert2_dir(:)
     343   [ +  +  +  - ]:        7698 :          if (i2pert>natom+11.and.i2pert<=2*natom+11) &
     344         [ +  + ]:        6624 :        & d3e_dir2(:)=dtset%d3e_pert2_magdir(:)
     345         [ +  + ]:       31158 :          do i2dir = 1, 3
     346         [ +  + ]:       53886 :            do i3pert = natom+9, natom+9
     347         [ +  + ]:      115470 :              do i3dir = 1, 3
     348                 :             :                perm(1)=d3e_pert1(i1pert)*d3e_dir1(i1dir)* &
     349                 :             :              &         d3e_pert2(i2pert)*d3e_dir2(i2dir)* &
     350                 :       69282 :              &         d3e_pert3(i3pert)*d3e_dir3(i3dir)
     351   [ +  +  +  + ]:      508068 :                if ( sum(perm(:)) > 0 ) rfpert(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)=1
     352                 :             :              end do
     353                 :             :            end do
     354                 :             :          end do
     355                 :             :        end do
     356                 :             :      end do
     357                 :             :    end do
     358                 :             :  end if
     359                 :             : 
     360                 :             : !Do symmetry stuff
     361   [ -  +  +  -  :          68 :  ABI_MALLOC(irrzon,(nfftot**(1-1/dtset%nsym),2,(dtset%nspden/dtset%nsppol)-3*(dtset%nspden/4)))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     362   [ -  +  +  -  :          68 :  ABI_MALLOC(phnons,(2,nfftot**(1-1/dtset%nsym),(dtset%nspden/dtset%nsppol)-3*(dtset%nspden/4)))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     363   [ -  +  +  -  :          68 :  ABI_MALLOC(indsym,(4,dtset%nsym,natom))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     364   [ -  +  +  -  :          51 :  ABI_MALLOC(symrec,(3,3,dtset%nsym))
          +  -  +  -  -  
                +  -  + ]
     365   [ +  +  +  +  :      715682 :  irrzon=0;indsym=0;symrec=0;phnons=zero
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
             +  +  +  +  
                      + ]
     366                 :             : !If the density is to be computed by mkrho, need irrzon and phnons
     367         [ +  - ]:          17 :  iscf_eff=0;if(dtset%getden==0)iscf_eff=1
     368                 :             :  call setsym(indsym,irrzon,iscf_eff,natom,&
     369                 :             : & nfftot,ngfft,dtset%nspden,dtset%nsppol,dtset%nsym,&
     370                 :          17 : & phnons,dtset%symafm,symrec,dtset%symrel,dtset%tnons,dtset%typat,xred)
     371                 :             : 
     372                 :             : !Symmetrize atomic coordinates over space group elements:
     373                 :          17 :  call symmetrize_xred(natom,dtset%nsym,dtset%symrel,dtset%tnons,xred,indsym=indsym)
     374                 :             : 
     375                 :             : ! Get symmetries in cartesian coordinates
     376                 :             : ! ABI_MALLOC(symrel_cart, (3, 3, dtset%nsym))
     377                 :             : ! do isym =1,dtset%nsym
     378                 :             : !   call symredcart(rprimd, gprimd, symrel_cart(:,:,isym), dtset%symrel(:,:,isym))
     379                 :             : !   ! purify operations in cartesian coordinates.
     380                 :             : !   where (abs(symrel_cart(:,:,isym)) < tol14)
     381                 :             : !     symrel_cart(:,:,isym) = zero
     382                 :             : !   end where
     383                 :             : ! end do
     384                 :             : 
     385                 :             : ! call sylwtens(indsym,mpert,natom,dtset%nsym,rfpert,symrec,dtset%symrel,symrel_cart)
     386                 :          17 :  call sylwtens(indsym,mpert,natom,dtset%nsym,rfpert,symrec,dtset%symrel)
     387                 :             : 
     388                 :          17 :  write(msg,'(a,a,a,a,a)') ch10, &
     389                 :          17 : & ' The list of irreducible elements of the spatial-dispersion third-order energy derivatives is: ', ch10,&
     390                 :          34 : & ' (in reduced coordinates except for strain and hspinfield perturbations) ', ch10
     391                 :          17 :  call wrtout(ab_out,msg,'COLL')
     392                 :          17 :  call wrtout(std_out,msg,'COLL')
     393                 :             : 
     394                 :          17 :  write(msg,'(12x,a)') 'i1dir   i1pert  i2dir   i2pert  i3dir  i3pert'
     395                 :          17 :  call wrtout(ab_out,msg,'COLL')
     396                 :          17 :  call wrtout(std_out,msg,'COLL')
     397                 :          17 :  n1 = 0
     398         [ +  + ]:         259 :  do i3pert = 1, mpert
     399         [ +  + ]:         985 :    do i3dir = 1, 3
     400         [ +  + ]:       12740 :      do i2pert = 1, mpert
     401         [ +  + ]:       47814 :        do i2dir = 1,3
     402         [ +  + ]:      690840 :          do i1pert = 1, mpert
     403         [ +  + ]:     2610324 :            do i1dir = 1, 3
     404         [ +  + ]:     2575008 :              if (rfpert(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)==1) then
     405                 :         611 :                n1 = n1 + 1
     406                 :         611 :                write(msg,'(2x,i4,a,6(5x,i3))') n1,')', &
     407                 :        1222 :              & i1dir,i1pert,i2dir,i2pert,i3dir,i3pert
     408                 :         611 :                call wrtout(ab_out,msg,'COLL')
     409                 :         611 :                call wrtout(std_out,msg,'COLL')
     410         [ +  + ]:     1930645 :              else if (rfpert(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)==-2) then
     411                 :         263 :                blkflg(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert) = 1
     412         [ -  + ]:         263 :                if (dtset%prtvol>=10) then
     413                 :           0 :                  n1 = n1 + 1
     414                 :           0 :                  write(msg,'(2x,i4,a,6(5x,i3),a)') n1,')', &
     415                 :           0 :   &               i1dir,i1pert,i2dir,i2pert,i3dir,i3pert,' => must be zero, not computed'
     416                 :           0 :                  call wrtout(ab_out,msg,'COLL')
     417                 :           0 :                  call wrtout(std_out,msg,'COLL')
     418                 :             :                end if
     419         [ +  + ]:     1930382 :              else if (rfpert(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)==-1) then
     420         [ -  + ]:         612 :                if (dtset%prtvol>=10) then
     421                 :           0 :                  n1 = n1 + 1
     422                 :           0 :                  write(msg,'(2x,i4,a,6(5x,i3),a)') n1,')', &
     423                 :           0 :   &               i1dir,i1pert,i2dir,i2pert,i3dir,i3pert,' => symmetric of another element, not computed'
     424                 :           0 :                  call wrtout(ab_out,msg,'COLL')
     425                 :           0 :                  call wrtout(std_out,msg,'COLL')
     426                 :             :                end if
     427                 :             :              end if
     428                 :             :            end do
     429                 :             :          end do
     430                 :             :        end do
     431                 :             :      end do
     432                 :             :    end do
     433                 :             :  end do
     434                 :          17 :  write(msg,'(a,a)') ch10,ch10
     435                 :          17 :  call wrtout(ab_out,msg,'COLL')
     436                 :          17 :  call wrtout(std_out,msg,'COLL')
     437                 :             : 
     438                 :             : !In some cases (e.g. getcell/=0), the plane wave vectors have
     439                 :             : !to be generated from the original simulation cell
     440                 :          17 :  rprimd_for_kg=rprimd
     441   [ -  +  -  -  :          17 :  if (dtset%getcell/=0.and.dtset%usewvl==0) rprimd_for_kg=dtset%rprimd_orig(:,:,1)
             -  -  -  - ]
     442                 :          17 :  call matr3inv(rprimd_for_kg,gprimd_for_kg)
     443   [ +  +  +  +  :         680 :  gmet_for_kg=matmul(transpose(gprimd_for_kg),gprimd_for_kg)
                   +  + ]
     444                 :             : 
     445                 :             : !Set up the basis sphere of planewaves
     446   [ -  +  +  -  :          51 :  ABI_MALLOC(kg,(3,dtset%mpw*dtset%mkmem))
          +  -  +  -  -  
                +  -  + ]
     447   [ -  +  +  -  :          51 :  ABI_MALLOC(npwarr,(dtset%nkpt))
          +  -  +  -  -  
                +  -  + ]
     448                 :             :  call kpgio(ecut_eff,dtset%exchn2n3d,gmet_for_kg,dtset%istwfk,kg,&
     449                 :             : & dtset%kptns,dtset%mkmem,dtset%nband,dtset%nkpt,'PERS',mpi_enreg,dtset%mpw,npwarr,npwtot,&
     450                 :          17 : & dtset%nsppol)
     451                 :             : 
     452                 :             : !Open and read pseudopotential files
     453                 :             :  ecore=zero
     454                 :             :  call pspini(dtset,dtfil,ecore,psp_gencond,gsqcutc_eff,gsqcut_eff,pawrad,pawtab,&
     455                 :          17 : & psps,rprimd,comm_mpi=mpi_enreg%comm_cell)
     456                 :             : 
     457                 :             : !Initialize band structure datatype
     458                 :          17 :  call bstruct%from_dtset(dtset, npwarr)
     459                 :             : 
     460                 :             : !Initialize PAW atomic occupancies to zero
     461         [ -  + ]:          17 :  ABI_MALLOC(pawrhoij,(0))
     462                 :             : 
     463                 :             : !Initialize header
     464                 :          17 :  gscase=0
     465                 :             :  call hdr%init(bstruct,codvsn,dtset,pawtab,gscase,psps,wvl%descr, &
     466                 :          17 : & comm_atom=mpi_enreg%comm_atom, mpi_atmtab=mpi_enreg%my_atmtab)
     467                 :             : 
     468                 :             : !Update header, with evolving variables, when available
     469                 :             : !Here, rprimd, xred and occ are available
     470                 :          17 :  etot=hdr%etot ; fermie=hdr%fermie ; fermih=hdr%fermih ; residm=hdr%residm
     471                 :             : 
     472                 :             : !If parallelism over atom, hdr is distributed
     473                 :             :  call hdr%update(bantot,etot,fermie,fermih,&
     474                 :             : & residm,rprimd,occ,pawrhoij,xred,dtset%amu_orig(:,1), &
     475                 :          17 : & comm_atom=mpi_enreg%comm_atom, mpi_atmtab=mpi_enreg%my_atmtab)
     476                 :             : 
     477                 :             : !Clean band structure datatype (should use it more in the future !)
     478                 :          17 :  call bstruct%free()
     479                 :             : 
     480                 :             : !Initialize wavefunction files and wavefunctions.
     481                 :          17 :  mcg=dtset%mpw*dtset%nspinor*dtset%mband*dtset%mkmem*dtset%nsppol
     482   [ -  +  +  -  :          51 :  ABI_STAT_MALLOC(cg,(2,mcg), ierr)
          +  -  +  -  +  
                -  -  + ]
     483         [ -  + ]:          17 :  ABI_CHECK(ierr==0, "out-of-memory in cg")
     484                 :             : 
     485   [ -  +  +  -  :          51 :  ABI_MALLOC(eigen0,(dtset%mband*dtset%nkpt*dtset%nsppol))
          +  -  +  -  -  
                +  -  + ]
     486         [ +  + ]:        7121 :  eigen0(:)=zero ; ask_accurate=1
     487                 :          17 :  optorth=0
     488                 :             : 
     489                 :          17 :  ireadwf0=1
     490   [ +  +  +  + ]:         221 :  hdr%rprimd=rprimd_for_kg ! We need the rprimd that was used to generate de G vectors
     491         [ +  + ]:          17 :  if (.not.just_timdisp) then
     492                 :             :    call inwffil(ask_accurate,cg,dtset,dtset%ecut,ecut_eff,eigen0,dtset%exchn2n3d,&
     493                 :             :   & formeig,hdr,ireadwf0,dtset%istwfk,kg,dtset%kptns,&
     494                 :             :   & dtset%localrdwf,dtset%mband,mcg,dtset%mkmem,mpi_enreg,dtset%mpw,&
     495                 :             :   & dtset%nband,ngfft,dtset%nkpt,npwarr,dtset%nsppol,dtset%nsym,&
     496                 :             :   & occ,optorth,dtset%symafm,dtset%symrel,dtset%tnons,&
     497                 :          11 :   & dtfil%unkg,wffgs,wfftgs,dtfil%unwffgs,dtfil%fnamewffk,wvl)
     498   [ +  +  +  + ]:         143 :    hdr%rprimd=rprimd
     499                 :             : 
     500                 :             :   !Close wffgs, if it was ever opened (in inwffil)
     501                 :          11 :    if (ireadwf0==1) then
     502                 :          11 :      call WffClose(wffgs,ierr)
     503                 :             :    end if
     504                 :             :  end if
     505                 :             : 
     506                 :             : !Generate an index table of atoms, in order for them to be used
     507                 :             : !type after type.
     508   [ -  +  +  -  :          51 :  ABI_MALLOC(atindx,(natom))
          +  -  +  -  -  
                +  -  + ]
     509   [ -  +  +  -  :          34 :  ABI_MALLOC(atindx1,(natom))
             -  +  -  + ]
     510   [ -  +  +  -  :          51 :  ABI_MALLOC(nattyp,(ntypat))
          +  -  +  -  -  
                +  -  + ]
     511                 :          48 :  indx=1
     512         [ +  + ]:          48 :  do itypat=1,ntypat
     513                 :          31 :    nattyp(itypat)=0
     514         [ +  + ]:         181 :    do iatom=1,natom
     515         [ +  + ]:         164 :      if(dtset%typat(iatom)==itypat)then
     516                 :          68 :        atindx(iatom)=indx
     517                 :          68 :        atindx1(indx)=iatom
     518                 :          68 :        indx=indx+1
     519                 :          68 :        nattyp(itypat)=nattyp(itypat)+1
     520                 :             :      end if
     521                 :             :    end do
     522                 :             :  end do
     523                 :             : 
     524                 :             : !Derivative of occupations is always zero for non metallic systems
     525   [ -  +  +  -  :          51 :  ABI_MALLOC(doccde,(dtset%mband*dtset%nkpt*dtset%nsppol))
          +  -  +  -  -  
                +  -  + ]
     526         [ +  + ]:        7121 :  doccde(:)=zero
     527                 :             : 
     528                 :             : !Read ground-state charge density from diskfile in case getden /= 0
     529                 :             : !or compute it from wfs that were read previously : rhor
     530                 :             : 
     531   [ -  +  +  -  :          51 :  ABI_MALLOC(rhog,(2,nfftf))
          +  -  +  -  -  
                +  -  + ]
     532   [ -  +  +  -  :          68 :  ABI_MALLOC(rhor,(nfftf,dtset%nspden))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     533                 :             : 
     534         [ +  + ]:          17 :  if (.not.just_timdisp) then
     535   [ +  -  -  + ]:          11 :    if (dtset%getden /= 0 .or. dtset%irdden /= 0) then
     536                 :             :      ! Read rho1(r) from a disk file and broadcast data.
     537                 :             :      ! This part is not compatible with MPI-FFT (note single_proc=.True. below)
     538                 :             : 
     539                 :           0 :      rdwrpaw=psps%usepaw
     540         [ #  # ]:           0 :      ABI_MALLOC(pawrhoij_read,(0))
     541                 :             : 
     542                 :             : !
     543                 :             :   !  MT july 2013: Should we read rhoij from the density file ?
     544                 :             :      call read_rhor(dtfil%fildensin, cplex1, dtset%nspden, nfftf, ngfftf, rdwrpaw, mpi_enreg, rhor, &
     545                 :           0 :      hdr_den, pawrhoij_read, spaceworld, check_hdr=hdr)
     546                 :           0 :      etotal = hdr_den%etot; call hdr_den%free()
     547                 :             : 
     548   [ #  #  #  #  :           0 :      ABI_FREE(pawrhoij_read)
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     549                 :             : 
     550                 :             :   !  Compute up+down rho(G) by fft
     551   [ #  #  #  #  :           0 :      ABI_MALLOC(work,(nfftf))
          #  #  #  #  #  
                #  #  # ]
     552         [ #  # ]:           0 :      work(:)=rhor(:,1)
     553                 :           0 :      call fourdp(1,rhog,work,-1,mpi_enreg,nfftf,1,ngfftf,0)
     554         [ #  # ]:           0 :      ABI_FREE(work)
     555                 :             :    else
     556                 :             :   !  Obtain the charge density from read wfs
     557                 :             :   !  Be careful: in PAW, compensation density has to be added !
     558                 :          11 :      tim_mkrho=4
     559                 :          11 :      paw_dmft%use_sc_dmft=0 ! respfn with dmft not implemented
     560                 :          11 :      paw_dmft%use_dmft=0 ! respfn with dmft not implemented
     561                 :             : 
     562                 :             :        call mkrho(cg,dtset,gprimd,irrzon,kg,mcg,&
     563                 :          11 :   &     mpi_enreg,npwarr,occ,paw_dmft,phnons,rhog,rhor,rprimd,tim_mkrho,ucvol,wvl%den,wvl%wfs)
     564                 :             :    end if ! getden
     565                 :             :   ! ABI_FREE(cg)
     566                 :             :  end if
     567                 :             : 
     568                 :             : !Compute large sphere cut-off gsqcut
     569                 :          17 :  call getcut(boxcut,dtset%ecut,gmet,gsqcut,dtset%iboxcut,std_out,dtset%qptn,dtset%ngfft)
     570                 :             : 
     571                 :             : !Generate the 1-dimensional phases
     572   [ +  -  -  +  :          51 :  ABI_MALLOC(ph1d,(2,3*(2*mgfftf+1)*dtset%natom))
          +  -  +  -  +  
             -  -  +  -  
                      + ]
     573                 :          17 :  call getph(atindx,dtset%natom,dtset%ngfft(1),dtset%ngfft(2),dtset%ngfft(3),ph1d,xred)
     574                 :             : 
     575                 :             : !Pseudo core electron density by method 2
     576                 :             : !TODO: The tasks to adapt the code to consider n3xccc in the long-wave
     577                 :             : !driver are under way.
     578         [ +  + ]:          17 :  n3xccc=0;if (psps%n1xccc/=0) n3xccc=nfftf
     579   [ +  +  +  -  :          51 :  ABI_MALLOC(xccc3d,(n3xccc))
          +  -  +  +  -  
                +  -  + ]
     580         [ +  + ]:          17 :  if (.not.just_timdisp) then
     581   [ -  +  +  -  :          44 :    ABI_MALLOC(ncorespl,(psps%mqgrid_vl,2,ntypat))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     582         [ +  + ]:          11 :    if (psps%n1xccc/=0) then
     583   [ -  +  +  -  :           6 :      ABI_MALLOC(dummy_dyfrx2,(3,3,natom)) ! dummy
          +  -  +  -  -  
                +  -  + ]
     584         [ -  + ]:           2 :      if (psps%nc_xccc_gspace==1) then
     585   [ #  #  #  #  :           0 :        ABI_MALLOC(dummy_vpsp,(nfftf))
          #  #  #  #  #  
                #  #  # ]
     586                 :           0 :        optatm=1;optdyfr=0;opteltfr=0;optgr=0;optstr=0;optv=0;optn=n3xccc/nfftf;optn2=1
     587                 :             :        call atm2fft(atindx1,xccc3d,dummy_vpsp,dummy_dyfrx2,dum_dyfrv,dum_eltfrxc,dum_gauss,gmet,gprimd,&
     588                 :             :     &   dum_grn,dum_grv,gsqcut,mgfftf,psps%mqgrid_vl,natom,nattyp,nfftf,ngfftf,&
     589                 :             :     &   ntypat,optatm,optdyfr,opteltfr,optgr,optn,optn2,optstr,optv,psps,pawtab,ph1d,psps%qgrid_vl,&
     590                 :           0 :     &   dtset%qprtrb,dtset%rcut,dum_rhog,rprimd,dummy6,other_dummy6,ucvol,psps%usepaw,dum_vg,dum_vg,dum_vg,dtset%vprtrb,psps%vlspl)
     591                 :             : 
     592         [ #  # ]:           0 :        ABI_FREE(dummy_vpsp)
     593                 :             :      end if
     594         [ +  - ]:           2 :      if (psps%nc_xccc_gspace==0) then
     595                 :           2 :        option=1
     596         [ -  + ]:           2 :        ABI_MALLOC(vxc,(0,0)) ! dummy
     597   [ -  +  +  -  :           6 :        ABI_MALLOC(grxc,(3,natom))
          +  -  +  -  -  
                +  -  + ]
     598                 :             :        call mkcore(dummy6,dummy_dyfrx2,grxc,mpi_enreg,natom,nfftf,dtset%nspden,ntypat,&
     599                 :             :     &   ngfftf(1),psps%n1xccc,ngfftf(2),ngfftf(3),option,rprimd,dtset%typat,ucvol,vxc,&
     600                 :           2 :     &   psps%xcccrc,psps%xccc1d,xccc3d,xred)
     601         [ -  + ]:           2 :        ABI_FREE(vxc) ! dummy
     602         [ -  + ]:           2 :        ABI_FREE(grxc) ! dummy
     603                 :             :      end if
     604         [ -  + ]:           2 :      ABI_FREE(dummy_dyfrx2) ! dummy
     605                 :             : 
     606                 :             :      !Write the spl interpolation of the pseudo core density for all atom types
     607         [ +  + ]:           6 :      do itypat= 1, ntypat
     608   [ +  +  +  + ]:       24022 :        ncorespl(:,:,itypat)= psps%nctab(itypat)%tcorespl(:,:)
     609                 :             :      end do
     610                 :             :    end if
     611                 :             :  end if
     612                 :             : 
     613                 :             : !Set up xc potential. Compute kxc here.
     614                 :             : !TODO: Iclude nonlinear core corrections (see m_respfn_driver.F90)
     615                 :          17 :  option=2 ; nk3xc=1
     616         [ +  + ]:          17 :  nkxc=2*min(dtset%nspden,2)-1;if(dtset%xclevel==2)nkxc=12*min(dtset%nspden,2)-5
     617                 :          17 :  call check_kxc(dtset%ixc,dtset%optdriver)
     618   [ -  +  +  -  :          68 :  ABI_MALLOC(kxc,(nfftf,nkxc))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     619   [ -  +  +  -  :          68 :  ABI_MALLOC(vxc,(nfftf,dtset%nspden))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     620                 :             : 
     621                 :          17 :  nhatgrdim=0;nhatdim=0
     622         [ -  + ]:          17 :  ABI_MALLOC(nhat,(0,0))
     623         [ -  + ]:          17 :  ABI_MALLOC(nhatgr,(0,0,0))
     624                 :          17 :  non_magnetic_xc=.false.
     625                 :             : 
     626                 :          17 :  usexcnhat=0
     627                 :          17 :  bigexc=zero
     628                 :          17 :  bigsxc=zero
     629                 :             : 
     630         [ +  + ]:          17 :  if (.not.just_timdisp) then
     631                 :          11 :    call xcdata_init(xcdata,dtset=dtset)
     632                 :             :    call rhotoxc(bigexc,bigsxc,kxc,mpi_enreg,nfftf,ngfftf,&
     633                 :             :   & nhat,nhatdim,nhatgr,nhatgrdim,nkxc,nk3xc,non_magnetic_xc,n3xccc,option,rhor,&
     634                 :          11 :   & rprimd,usexcnhat,vxc,vxcavg,xccc3d,xcdata)
     635                 :             :  end if
     636                 :             : 
     637         [ -  + ]:          17 :  ABI_FREE(xccc3d)
     638                 :             : 
     639                 :             : !Set up the spherical harmonics (Ylm) and gradients at each k point
     640         [ +  + ]:          17 :  if (psps%useylm==1) then
     641                 :          11 :    useylmgr=1; option=2 ; nylmgr=9
     642   [ -  +  +  -  :          44 :    ABI_MALLOC(ylm,(dtset%mpw*dtset%mkmem,psps%mpsang*psps%mpsang*psps%useylm))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     643   [ -  +  +  -  :          55 :    ABI_MALLOC(ylmgr,(dtset%mpw*dtset%mkmem,nylmgr,psps%mpsang*psps%mpsang*psps%useylm*useylmgr))
          +  -  -  +  +  
          -  +  -  +  -  
             -  +  -  + ]
     644         [ +  - ]:          11 :    if (.not.just_timdisp) then
     645                 :             :      call initylmg(gprimd,kg,dtset%kptns,dtset%mkmem,mpi_enreg,&
     646                 :             :    & psps%mpsang,dtset%mpw,dtset%nband,dtset%nkpt,npwarr,dtset%nsppol,option,&
     647                 :          11 :    & rprimd,ylm,ylmgr)
     648                 :             :    end if
     649                 :             :  end if
     650                 :             : 
     651                 :             : !Compute nonlocal form factors ffnl1, for all atoms and all k-points.
     652         [ +  + ]:          17 :  if (dtset%ffnl_lw == 0) then
     653         [ +  + ]:          16 :    if (dtset%lw_natopt==1) then
     654                 :           1 :      ider=1;dimffnl=4;dimffnl_i=2
     655   [ -  +  +  -  :           7 :      ABI_MALLOC(ffnl,(dtset%mkmem,dtset%mpw,dimffnl,psps%lmnmax,psps%ntypat))
          -  +  +  -  +  
          -  -  +  +  -  
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     656   [ -  +  +  -  :           7 :      ABI_MALLOC(ffnl_i,(dtset%mkmem,dtset%mpw,dimffnl_i,psps%lmnmax,psps%ntypat))
          -  +  +  -  +  
          -  -  +  +  -  
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     657         [ +  + ]:           4 :      do idir=1, 3
     658                 :           3 :        idir0=idir
     659         [ +  - ]:           3 :        if (.not.just_timdisp) then
     660                 :             :          call preca_ffnl(dimffnl_i,ffnl_i,gmet,gprimd,ider,idir0,kg, &
     661                 :             :        & dtset%kptns,dtset%mband,dtset%mkmem,mpi_enreg,dtset%mpw, &
     662                 :           3 :        & dtset%nkpt,npwarr,nylmgr,psps,rmet,useylmgr,ylm,ylmgr)
     663                 :             :        end if
     664   [ +  +  +  +  :      284157 :        ffnl(:,:,1,:,:)=ffnl_i(:,:,1,:,:)
             +  +  +  + ]
     665   [ +  +  +  +  :      284158 :        ffnl(:,:,1+idir,:,:)=ffnl_i(:,:,2,:,:)
             +  +  +  + ]
     666                 :             :      end do
     667         [ -  + ]:           1 :      ABI_FREE(ffnl_i)
     668         [ +  - ]:           1 :      if (psps%useylm==1) then
     669                 :           1 :        useylmgr=0
     670         [ -  + ]:           1 :        ABI_FREE(ylmgr)
     671   [ -  +  +  -  :           3 :        ABI_MALLOC(ylmgr,(dtset%mpw*dtset%mkmem,nylmgr,psps%mpsang*psps%mpsang*psps%useylm*useylmgr))
          -  +  +  -  -  
                +  -  + ]
     672                 :             :      end if
     673                 :             :    else
     674   [ +  +  -  + ]:          15 :      if (dtset%lw_qdrpl==1.or.dtset%lw_flexo==3) ider=1; idir0=4; dimffnl=4
     675         [ +  + ]:          15 :      if (dtset%lw_flexo==1.or.dtset%lw_flexo==2.or.dtset%lw_flexo==4) then
     676                 :           2 :        ider=2; idir0=4; dimffnl=10
     677                 :             :      end if
     678   [ -  +  +  -  :         105 :      ABI_MALLOC(ffnl,(dtset%mkmem,dtset%mpw,dimffnl,psps%lmnmax,psps%ntypat))
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  -  +  +  
          -  +  -  +  -  
             -  +  -  + ]
     679         [ +  + ]:          15 :      if (.not.just_timdisp) then
     680                 :             :        call preca_ffnl(dimffnl,ffnl,gmet,gprimd,ider,idir0,kg, &
     681                 :             :      & dtset%kptns,dtset%mband,dtset%mkmem,mpi_enreg,dtset%mpw, &
     682                 :           9 :      & dtset%nkpt,npwarr,nylmgr,psps,rmet,useylmgr,ylm,ylmgr)
     683                 :             :      end if
     684                 :          15 :      useylmgr=0
     685         [ +  + ]:          15 :      ABI_SFREE(ylmgr)
     686   [ -  +  +  -  :          45 :      ABI_MALLOC(ylmgr,(dtset%mpw*dtset%mkmem,nylmgr,psps%mpsang*psps%mpsang*psps%useylm*useylmgr))
          -  +  +  -  -  
             +  -  +  -  
                      + ]
     687                 :             :    end if
     688         [ +  - ]:           1 :  else if (dtset%ffnl_lw == 1) then
     689                 :           1 :    dimffnl=0
     690   [ -  +  +  -  :           5 :    ABI_MALLOC(ffnl,(dtset%mkmem,dtset%mpw,dimffnl,psps%lmnmax,psps%ntypat))
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  -  +  -  
                      + ]
     691                 :             :  end if
     692                 :             : 
     693                 :             : !#############  SPATIAL-DISPERSION PROPERTIES CALCULATION  ###########################
     694                 :             : 
     695                 :             : !Anounce start of spatial-dispersion calculation
     696         [ +  + ]:        1394 :  write(msg, '(a,80a,a,a,a)' ) ch10,('=',ii=1,80),ch10,&
     697         [ +  - ]:        1411 : &   ' ==> Compute spatial-dispersion 3rd-order energy derivatives <== ',ch10
     698                 :          17 :  call wrtout(std_out,msg,'COLL')
     699                 :          17 :  call wrtout(ab_out,msg,'COLL')
     700                 :             : 
     701         [ -  + ]:          17 :  if (dtset%prtvol>=10) then
     702                 :           0 :    write(msg,'(5a)') ' CAUTION: Individual contributions to the 3rd-order energy derivatives ',ch10, &
     703                 :           0 :                    & ' are not written in a unified form. Mixed cartesian/reduced coordinates ',ch10, &
     704                 :           0 :                    & ' and/or type-I/type-II forms are used.'
     705                 :           0 :    call wrtout(std_out,msg,'COLL')
     706                 :           0 :    call wrtout(ab_out,msg,'COLL')
     707                 :             :  end if
     708                 :             : 
     709                 :             : !Calculate the nonvariational Ewald terms
     710   [ +  +  -  + ]:          17 :  if (dtset%lw_flexo==1.or.dtset%lw_flexo==3.or.dtset%lw_flexo==4) then
     711                 :             :    call dfptlw_nv(d3etot_nv,dtset,gmet,gprimd,mpert,my_natom,rfpert,rmet,rprimd,ucvol,xred,psps%ziontypat, &
     712                 :           3 :   & mpi_atmtab=mpi_enreg%my_atmtab,comm_atom=mpi_enreg%comm_atom)
     713                 :             :  end if
     714                 :             : 
     715                 :             : !Main loop over the perturbations to calculate the stationary part
     716                 :             :  call dfptlw_loop(atindx,blkflg,cg,codvsn,d3e_pert1,d3e_pert2,d3etot,dimffnl,dtfil,dtset,&
     717                 :             : & ffnl,gmet,gprimd,gsqcut,&
     718                 :             : & hdr,just_timdisp,kg,kxc,dtset%mband,dtset%mgfft,&
     719                 :             : & dtset%mkmem,dtset%mk1mem,mpert,mpi_enreg,dtset%mpw,natom,nattyp,ncorespl,ngfftf,nfftf,&
     720                 :             : & dtset%nkpt,nkxc,dtset%nspinor,dtset%nsppol,npwarr,nylmgr,occ,&
     721                 :             : & pawfgr,pawtab,ph1d,&
     722                 :          17 : & psps,rfpert,rhog,rhor,rmet,rprimd,ucvol,useylmgr,xred,ylm,ylmgr)
     723                 :             : 
     724                 :             : !Merge stationay and nonvariational contributions
     725   [ +  +  +  +  :     6485593 :  d3etot(:,:,:,:,:,:,:)=d3etot(:,:,:,:,:,:,:) + d3etot_nv(:,:,:,:,:,:,:)
          +  +  +  +  +  
             +  +  +  +  
                      + ]
     726                 :             : 
     727                 :             : !Real (imaginary) part of d3etot is zero for first (second) momentum derivatives
     728         [ +  + ]:          17 :  if (dtset%kptopt /= 3) then
     729         [ +  + ]:         131 :    do i3pert = 1, mpert
     730         [ +  - ]:         120 :      if (i3pert == natom+9 ) cycle
     731         [ +  + ]:         491 :      do i3dir = 1, 3
     732         [ +  + ]:        4554 :        do i2pert = 1, mpert
     733         [ +  + ]:       16656 :          do i2dir = 1,3
     734         [ +  + ]:      161286 :            do i1pert = 1, mpert
     735         [ +  + ]:      592182 :              do i1dir = 1, 3
     736         [ +  + ]:      579960 :                if (blkflg(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert) == 1) then
     737   [ +  +  +  + ]:         854 :                  if (i2pert /= natom+3 .and. i2pert /= natom+4) then
     738                 :         368 :                    d3etot(1,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert) = zero
     739                 :             :                  else
     740                 :         486 :                    d3etot(2,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert) = zero
     741                 :             :                  end if
     742                 :             :                end if
     743                 :             :              end do
     744                 :             :            end do
     745                 :             :          end do
     746                 :             :        end do
     747                 :             :      end do
     748                 :             :    end do
     749                 :             :  end if
     750                 :             : 
     751                 :             : 
     752                 :             : !Complete missing elements using symmetry operations
     753                 :             : ! has_strain=.false.
     754                 :             : ! if (dtset%lw_flexo==1.or.dtset%lw_flexo==2.or.dtset%lw_flexo==4) has_strain=.true.
     755                 :             : ! call d3lwsym(blkflg,d3etot,has_strain,indsym,mpert,natom,dtset%nsym,symrec,dtset%symrel,symrel_cart)
     756                 :          17 :  call d3lwsym(blkflg,d3etot,indsym,mpert,natom,dtset%nsym,symrec,dtset%symrel)
     757                 :             : 
     758                 :             : !Deallocate global proc_distrib
     759                 :          17 :  if(xmpi_paral==1) then
     760         [ -  + ]:          17 :    ABI_FREE(mpi_enreg%proc_distrb)
     761                 :             :  end if
     762                 :             : 
     763                 :             : ! Write the DDB file
     764                 :             :  call ddb_hdr%init(dtset,psps,pawtab,&
     765                 :             :                    dscrpt=' Note : temporary (transfer) database ',&
     766                 :          17 :                    nblok=1,xred=xred,occ=occ)
     767                 :             : 
     768                 :          17 :  call ddb%init(dtset, 1, mpert, with_d3E=.true.)
     769                 :             : 
     770                 :          17 :  call ddb%set_omega(iblok=1, omega=dtset%rfomega)
     771                 :             : 
     772                 :          17 :  call ddb%set_qpt(iblok=1, qpt=dtset%qptn(1:3))
     773                 :             : 
     774                 :          17 :  call ddb%set_d3matr(1, d3etot, blkflg, lw=.true.)
     775                 :             : 
     776                 :          17 :  call ddb%write_txt(ddb_hdr, dtfil%fnameabo_ddb)
     777                 :             : 
     778                 :          17 :  call ddb_hdr%free()
     779                 :          17 :  call ddb%free()
     780                 :             : 
     781                 :             :  !Calculate spatial-dispersion quantities in Cartesian coordinates and write
     782                 :             :  !them in abi_out
     783   [ -  +  +  -  :         119 :  ABI_MALLOC(blkflg_car,(3,mpert,3,mpert,3,mpert))
          +  -  -  +  +  
          -  +  -  -  +  
          +  -  +  -  +  
             -  -  +  -  
                      + ]
     784   [ -  +  +  -  :         119 :  ABI_MALLOC(d3etot_car,(2,3,mpert,3,mpert,3,mpert))
          +  -  -  +  +  
          -  +  -  -  +  
          +  -  +  -  +  
             -  -  +  -  
                      + ]
     785                 :          17 :  call lwcart(blkflg,blkflg_car,d3etot,d3etot_car,gprimd,mpert,natom,rprimd)
     786         [ +  - ]:          17 :  if (me==0) then
     787                 :          17 :    call dfptlw_out(blkflg_car,d3etot_car,dtset%lw_flexo,dtset%lw_qdrpl,dtset%lw_natopt,mpert,natom,dtset%timdisp,ucvol)
     788                 :             :  end if
     789                 :             : 
     790                 :             : !Deallocate arrays
     791         [ -  + ]:          17 :  ABI_FREE(atindx)
     792         [ -  + ]:          17 :  ABI_FREE(atindx1)
     793         [ -  + ]:          17 :  ABI_FREE(blkflg)
     794         [ -  + ]:          17 :  ABI_FREE(doccde)
     795         [ -  + ]:          17 :  ABI_FREE(eigen0)
     796         [ -  + ]:          17 :  ABI_FREE(cg)
     797         [ -  + ]:          17 :  ABI_FREE(ph1d)
     798         [ +  - ]:          17 :  ABI_SFREE(ffnl)
     799         [ -  + ]:          17 :  ABI_FREE(indsym)
     800         [ -  + ]:          17 :  ABI_FREE(irrzon)
     801         [ -  + ]:          17 :  ABI_FREE(nattyp)
     802         [ -  + ]:          17 :  ABI_FREE(kg)
     803         [ -  + ]:          17 :  ABI_FREE(kxc)
     804         [ -  + ]:          17 :  ABI_FREE(npwarr)
     805         [ -  + ]:          17 :  ABI_FREE(phnons)
     806         [ -  + ]:          17 :  ABI_FREE(rhog)
     807         [ -  + ]:          17 :  ABI_FREE(rhor)
     808         [ -  + ]:          17 :  ABI_FREE(symrec)
     809                 :             : ! ABI_FREE(symrel_cart)
     810         [ -  + ]:          17 :  ABI_FREE(vxc)
     811         [ -  + ]:          17 :  ABI_FREE(d3etot)
     812         [ -  + ]:          17 :  ABI_FREE(d3etot_nv)
     813                 :             : ! ABI_FREE(pertsy)
     814         [ -  + ]:          17 :  ABI_FREE(rfpert)
     815         [ -  + ]:          17 :  ABI_FREE(d3e_pert1)
     816         [ -  + ]:          17 :  ABI_FREE(d3e_pert2)
     817         [ -  + ]:          17 :  ABI_FREE(d3e_pert3)
     818   [ +  -  -  +  :          17 :  ABI_SFREE(pawrhoij)
          -  -  -  -  -  
          -  -  -  -  -  
                   -  - ]
     819         [ +  - ]:          17 :  ABI_SFREE(nhat)
     820         [ +  - ]:          17 :  ABI_SFREE(nhatgr)
     821         [ +  + ]:          17 :  ABI_SFREE(ylm)
     822         [ +  - ]:          17 :  ABI_SFREE(ylmgr)
     823         [ +  - ]:          17 :  ABI_SFREE(blkflg_car)
     824         [ +  - ]:          17 :  ABI_SFREE(d3etot_car)
     825         [ +  + ]:          17 :  ABI_SFREE(ncorespl)
     826                 :          17 :  call pawfgr_destroy(pawfgr)
     827                 :             : 
     828                 :             :  ! Clean the header
     829                 :          17 :  call hdr%free()
     830                 :             : 
     831                 :             :  DBG_EXIT("COLL")
     832                 :             : 
     833   [ -  +  -  +  :          34 : end subroutine longwave
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          +  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  +  -  +  
          -  +  -  +  -  
          +  -  -  -  -  
          -  -  -  -  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                +  -  + ]
     834                 :             : !!***
     835                 :             : 
     836                 :             : !!****f* ABINIT/m_dfptlw_loop/dfptlw_out
     837                 :             : !! NAME
     838                 :             : !!  dfptlw_out
     839                 :             : !!
     840                 :             : !! FUNCTION
     841                 :             : !!  Write the relevant spatial-dispersion quantities in Cartesian coordinates
     842                 :             : !!
     843                 :             : !! COPYRIGHT
     844                 :             : !!  Copyright (C) 2022-2026 ABINIT group (MR)
     845                 :             : !!  This file is distributed under the terms of the
     846                 :             : !!  GNU General Public License, see ~abinit/COPYING
     847                 :             : !!  or http://www.gnu.org/copyleft/gpl.txt .
     848                 :             : !!
     849                 :             : !! INPUTS
     850                 :             : !!  blkflg_car(3,mpert,3,mpert,3,mpert) =flags for each element of the 3DTE
     851                 :             : !!  d3etot_car(2,3,mpert,3,mpert,3,mpert) =array with the cartesian thir-order derivatives
     852                 :             : !!  lw_qdrpl= flag that activates quadrupoles calculation
     853                 :             : !!  lw_flexo= flag that activates flexoelectric tensor calculation
     854                 :             : !!  mpert =maximum number of ipert
     855                 :             : !!  natom = number of atoms in unit cell
     856                 :             : !!  timdisp = if 1 write derivatives with respect to omega
     857                 :             : !!
     858                 :             : !! OUTPUT
     859                 :             : !!
     860                 :             : !! SIDE EFFECTS
     861                 :             : !!
     862                 :             : !! SOURCE
     863                 :             : 
     864                 :          17 : subroutine dfptlw_out(blkflg_car,d3etot_car,lw_flexo,lw_qdrpl,lw_natopt,mpert,natom,timdisp,ucvol)
     865                 :             : 
     866                 :             : !Arguments ------------------------------------
     867                 :             : !scalars
     868                 :             :  integer,intent(in) :: lw_flexo,lw_qdrpl,lw_natopt,mpert,natom,timdisp
     869                 :             :  real(dp),intent(in) :: ucvol
     870                 :             : !arrays
     871                 :             :  integer,intent(in) :: blkflg_car(3,mpert,3,mpert,3,mpert)
     872                 :             :  real(dp),intent(in) :: d3etot_car(2,3,mpert,3,mpert,3,mpert)
     873                 :             : 
     874                 :             : !Local variables-------------------------------
     875                 :             : !scalar
     876                 :             :  integer :: beta,delta,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert,istr
     877                 :             : !arrays
     878                 :             :  integer,save :: idx(18)=(/1,1,2,2,3,3,3,2,3,1,2,1,2,3,1,3,1,2/)
     879                 :          17 :  real(dp),allocatable :: qdrp(:,:,:,:,:,:,:)
     880                 :             :  real(dp) :: piezoci(2),piezofr(2),celastci(2)
     881                 :             : 
     882                 :             : ! *************************************************************************
     883                 :             : 
     884                 :             :  DBG_ENTER("COLL")
     885                 :             : 
     886                 :          17 :  i3pert=natom+8
     887   [ +  +  +  -  :          17 :  if (lw_qdrpl==1.or.lw_flexo==3.or.lw_flexo==1) then
                   +  + ]
     888                 :          10 :    write(ab_out,'(a)')' First real-space moment of the polarization response '
     889                 :          10 :    write(ab_out,'(a)')' to an atomic displacementatom, in cartesian coordinates,'
     890                 :          10 :    write(ab_out,'(a)')' (1/ucvol factor not included),'
     891                 :          10 :    write(ab_out,'(a)')' efidir   atom   atdir    qgrdir          real part        imaginary part'
     892                 :          10 :    i1pert=natom+2
     893         [ +  + ]:          40 :    do i3dir=1,3
     894         [ +  + ]:         120 :      do i1dir=1,3
     895         [ +  + ]:         327 :        do i2pert=1,natom
     896         [ +  + ]:         918 :          do i2dir=1,3
     897         [ +  - ]:         828 :            if (blkflg_car(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)==1) then
     898                 :         621 :              write(ab_out,'(4(i5,3x),2(1x,f20.10))') i1dir,i2pert,i2dir,i3dir, &
     899                 :         621 :            & d3etot_car(2,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert), &
     900                 :        1242 :            & -d3etot_car(1,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)
     901                 :             :            end if
     902                 :             :          end do
     903                 :             :        end do
     904                 :             :      end do
     905                 :          40 :      write(ab_out,*)' '
     906                 :             :    end do
     907                 :             : 
     908                 :             :    !Calculate cuadrupoles (symmetrize i1dir/i3dir)
     909   [ -  +  +  -  :          70 :    ABI_MALLOC(qdrp,(2,3,mpert,3,mpert,3,mpert))
          +  -  -  +  +  
          -  +  -  -  +  
          +  -  +  -  +  
             -  -  +  -  
                      + ]
     910                 :             :    i1pert=natom+2
     911         [ +  + ]:          33 :    do i2pert=1,natom
     912         [ +  + ]:         102 :      do i2dir=1,3
     913         [ +  + ]:         299 :        do i1dir=1,3
     914         [ +  + ]:         414 :          do i3dir=1,i1dir-1
     915         [ +  - ]:         414 :            if (blkflg_car(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)==1) then
     916                 :             :              !real part
     917                 :             :              qdrp(1,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)=&
     918                 :             :            & d3etot_car(2,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert) + &
     919                 :         207 :            & d3etot_car(2,i3dir,i1pert,i2dir,i2pert,i1dir,i3pert)
     920                 :             : 
     921                 :             :              qdrp(1,i3dir,i1pert,i2dir,i2pert,i1dir,i3pert)=&
     922                 :         207 :            & qdrp(1,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)
     923                 :             : 
     924                 :             :              !imaginary part
     925                 :             :              qdrp(2,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)=&
     926                 :             :            & -(d3etot_car(1,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert) + &
     927                 :         207 :            &   d3etot_car(1,i3dir,i1pert,i2dir,i2pert,i1dir,i3pert) )
     928                 :             : 
     929                 :             :              qdrp(2,i3dir,i1pert,i2dir,i2pert,i1dir,i3pert)=&
     930                 :         207 :            & qdrp(2,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)
     931                 :             :            end if
     932                 :             :          end do
     933         [ +  - ]:         276 :          if (blkflg_car(i1dir,i1pert,i2dir,i2pert,i1dir,i3pert)==1) then
     934                 :             :            !real part
     935                 :             :            qdrp(1,i1dir,i1pert,i2dir,i2pert,i1dir,i3pert)=&
     936                 :         207 :          & two*d3etot_car(2,i1dir,i1pert,i2dir,i2pert,i1dir,i3pert)
     937                 :             : 
     938                 :             :            !imaginary part
     939                 :             :            qdrp(2,i1dir,i1pert,i2dir,i2pert,i1dir,i3pert)=&
     940                 :         207 :          &-two*d3etot_car(1,i1dir,i1pert,i2dir,i2pert,i1dir,i3pert)
     941                 :             :          end if
     942                 :             :        end do
     943                 :             :      end do
     944                 :             :    end do
     945                 :             : 
     946                 :          10 :    write(ab_out,'(a)')' Quadrupole tensor, in cartesian coordinates,'
     947                 :          10 :    write(ab_out,'(a)')' efidir   atom   atdir    qgrdir          real part        imaginary part'
     948         [ +  + ]:          40 :    do i3dir=1,3
     949         [ +  + ]:         120 :      do i1dir=1,3
     950         [ +  + ]:         327 :        do i2pert=1,natom
     951         [ +  + ]:         918 :          do i2dir=1,3
     952         [ +  - ]:         828 :            if (blkflg_car(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)==1) then
     953                 :         621 :              write(ab_out,'(4(i5,3x),2(1x,f20.10))') i1dir,i2pert,i2dir,i3dir, &
     954                 :         621 :            & qdrp(1,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert), &
     955                 :        1242 :            & qdrp(2,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)
     956                 :             :            end if
     957                 :             :          end do
     958                 :             :        end do
     959                 :             :      end do
     960                 :          40 :      write(ab_out,*)' '
     961                 :             :    end do
     962                 :             : 
     963                 :          10 :    write(ab_out,'(a)')' Electronic (clamped-ion) contribution to the piezoelectric tensor,'
     964                 :          10 :    write(ab_out,'(a)')' in cartesian coordinates, (from sum rule of P^1 tensor)'
     965                 :          10 :    write(ab_out,'(a)')' efidir   atdir    qgrdir        real part           imaginary part'
     966         [ +  + ]:          40 :    do i3dir=1,3
     967         [ +  + ]:         120 :      do i1dir=1,3
     968         [ +  + ]:         390 :        do i2dir=1,3
     969                 :         270 :          piezoci=zero
     970         [ +  + ]:         891 :          do i2pert=1,natom
     971         [ +  - ]:         891 :            if (blkflg_car(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)==1) then
     972                 :         621 :              piezoci(1)=piezoci(1)+d3etot_car(2,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)
     973                 :         621 :              piezoci(2)=piezoci(2)-d3etot_car(1,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)
     974                 :             :            end if
     975                 :             :          end do
     976                 :         270 :          piezoci(1)=-piezoci(1)/ucvol
     977                 :         270 :          piezoci(2)=-piezoci(2)/ucvol
     978                 :         360 :          write(ab_out,'(3(i5,3x),2(1x,f20.10))') i1dir,i2dir,i3dir,piezoci(1),piezoci(2)
     979                 :             :        end do
     980                 :             :      end do
     981                 :          40 :      write(ab_out,*)' '
     982                 :             :    end do
     983                 :             : 
     984                 :          10 :    write(ab_out,'(a)')' Electronic (clamped-ion) contribution to the piezoelectric tensor,'
     985                 :          10 :    write(ab_out,'(a)')' in cartesian coordinates, (from sum rule of dynamic quadrupoles)'
     986                 :          10 :    write(ab_out,'(a)')' efidir   atdir    qgrdir        real part           imaginary part'
     987         [ +  + ]:          40 :    do i3dir=1,3
     988         [ +  + ]:         120 :      do i1dir=1,3
     989         [ +  + ]:         390 :        do i2dir=1,3
     990                 :         270 :          piezoci=zero
     991         [ +  + ]:         891 :          do i2pert=1,natom
     992                 :             :            if (blkflg_car(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)==1.and. &
     993   [ +  -  +  -  :         621 :                blkflg_car(i1dir,i1pert,i3dir,i2pert,i2dir,i3pert)==1.and. &
                   +  - ]
     994                 :         270 :                blkflg_car(i2dir,i1pert,i1dir,i2pert,i3dir,i3pert)==1) then
     995                 :             :              piezoci(1)=piezoci(1)+qdrp(1,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert) &
     996                 :             :            &                      +qdrp(1,i1dir,i1pert,i3dir,i2pert,i2dir,i3pert) &
     997                 :         621 :            &                      -qdrp(1,i2dir,i1pert,i1dir,i2pert,i3dir,i3pert)
     998                 :             :              piezoci(2)=piezoci(2)+qdrp(2,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert) &
     999                 :             :            &                      +qdrp(2,i1dir,i1pert,i3dir,i2pert,i2dir,i3pert) &
    1000                 :         621 :            &                      -qdrp(2,i2dir,i1pert,i1dir,i2pert,i3dir,i3pert)
    1001                 :             :            end if
    1002                 :             :          end do
    1003                 :         270 :          piezoci(1)=-piezoci(1)/(two*ucvol)
    1004                 :         270 :          piezoci(2)=-piezoci(2)/(two*ucvol)
    1005                 :         360 :          write(ab_out,'(3(i5,3x),2(1x,f20.10))') i1dir,i2dir,i3dir,piezoci(1),piezoci(2)
    1006                 :             :        end do
    1007                 :             :      end do
    1008                 :          40 :      write(ab_out,*)' '
    1009                 :             :    end do
    1010         [ -  + ]:          10 :    ABI_FREE(qdrp)
    1011                 :             :  end if
    1012                 :             : 
    1013         [ +  + ]:          17 :  if (lw_flexo==2.or.lw_flexo==1) then
    1014                 :           3 :    write(ab_out,'(a)')' Clamped-ion flexoelectric tensor (type-II), in cartesian coordinates,'
    1015                 :           3 :    write(ab_out,'(a)')' efidir  qgrdir  strdir1  strdir2         real part          imaginary part'
    1016                 :           3 :    i1pert=natom+2
    1017         [ +  + ]:          12 :    do i3dir=1,3
    1018         [ +  + ]:          30 :      do i2pert=natom+3,natom+4
    1019         [ +  + ]:          72 :        do i2dir=1,3
    1020                 :          54 :          istr=(i2pert-natom-3)*3+i2dir
    1021                 :          54 :          beta=idx(2*istr-1); delta=idx(2*istr)
    1022         [ +  + ]:         234 :          do i1dir=1,3
    1023         [ +  - ]:         216 :            if (blkflg_car(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)==1) then
    1024                 :         162 :              write(ab_out,'(4(i5,3x),2(1x,f20.10))') i1dir,i3dir,beta,delta, &
    1025                 :         162 :            & d3etot_car(1,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)/ucvol, &
    1026                 :         324 :            & d3etot_car(2,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)/ucvol
    1027                 :             :            end if
    1028                 :             :          end do
    1029                 :             :        end do
    1030                 :          27 :        write(ab_out,*)' '
    1031                 :             :      end do
    1032                 :             :    end do
    1033                 :             :  end if
    1034                 :             : 
    1035         [ +  + ]:          17 :  if (lw_flexo==3.or.lw_flexo==1) then
    1036                 :           3 :    write(ab_out,'(a)')' 1st real-space moment of IFCs, in cartesian coordinates,'
    1037                 :           3 :    write(ab_out,'(a)')' iatdir   iatom    jatdir   jatom    qgrdir           real part          imaginary part'
    1038         [ +  + ]:          12 :    do i3dir=1,3
    1039         [ +  + ]:          27 :      do i1pert=1,natom
    1040         [ +  + ]:          81 :        do i1dir=1,3
    1041         [ +  + ]:         180 :          do i2pert=1,natom
    1042         [ +  + ]:         486 :            do i2dir=1,3
    1043         [ +  - ]:         432 :              if (blkflg_car(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)==1) then
    1044                 :         324 :                write(ab_out,'(5(i5,4x),2(1x,f20.10))') i1dir,i1pert,i2dir,i2pert,i3dir, &
    1045                 :         324 :              & -d3etot_car(2,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert),&
    1046                 :         648 :              &  d3etot_car(1,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)
    1047                 :             :              end if
    1048                 :             :            end do
    1049                 :             :          end do
    1050                 :             :        end do
    1051                 :             :      end do
    1052                 :          12 :      write(ab_out,*)' '
    1053                 :             :    end do
    1054                 :             : 
    1055                 :           3 :    write(ab_out,'(a)')' Piezoelectric force-response tensor, in cartesian coordinates '
    1056                 :           3 :    write(ab_out,'(a)')' (from sum rule of 1st moment of IFCs),'
    1057                 :           3 :    write(ab_out,'(a)')' (for non-vanishing forces in the cell it lacks an improper contribution),'
    1058                 :           3 :    write(ab_out,'(a)')' iatom   iatddir  jatddir   qgrdir           real part          imaginary part'
    1059         [ +  + ]:          12 :    do i3dir=1,3
    1060         [ +  + ]:          27 :      do i1pert=1,natom
    1061         [ +  + ]:          81 :        do i1dir=1,3
    1062         [ +  + ]:         234 :          do i2dir=1,3
    1063                 :         162 :            piezofr=zero
    1064         [ +  + ]:         486 :            do i2pert=1,natom
    1065         [ +  - ]:         486 :              if (blkflg_car(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)==1) then
    1066                 :         324 :                piezofr(1)=piezofr(1)-d3etot_car(2,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)
    1067                 :         324 :                piezofr(2)=piezofr(2)+d3etot_car(1,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)
    1068                 :             :              end if
    1069                 :             :            end do
    1070                 :         162 :            write(ab_out,'(4(i5,4x),2(1x,f20.10))') i1pert,i1dir,i2dir,i3dir, &
    1071                 :         378 :          & piezofr(1), piezofr(2)
    1072                 :             :          end do
    1073                 :             :        end do
    1074                 :             :      end do
    1075                 :          12 :      write(ab_out,*)' '
    1076                 :             :    end do
    1077                 :             :  end if
    1078                 :             : 
    1079         [ +  + ]:          17 :  if (lw_flexo==4.or.lw_flexo==1) then
    1080                 :           3 :    write(ab_out,'(a)')' Clamped-ion flexoelectric force-response tensor (type-II),  in cartesian coordinates,'
    1081                 :           3 :    write(ab_out,'(a)')'  atom   atdir   qgrdir  strdir1 strdir2          real part          imaginary part'
    1082         [ +  + ]:          12 :    do i3dir=1,3
    1083         [ +  + ]:          30 :      do i1pert=1,natom
    1084         [ +  + ]:          81 :        do i1dir=1,3
    1085         [ +  + ]:         162 :          do i2pert=natom+3, natom+4
    1086         [ +  + ]:         486 :            do i2dir=1,3
    1087                 :         324 :              istr=(i2pert-natom-3)*3+i2dir
    1088                 :         324 :              beta=idx(2*istr-1); delta=idx(2*istr)
    1089         [ +  - ]:         432 :              if (blkflg_car(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)==1) then
    1090                 :         324 :                write(ab_out,'(5(i5,3x),2(1x,f20.10))') i1pert,i1dir,i3dir,beta,delta, &
    1091                 :         324 :              & d3etot_car(1,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert),&
    1092                 :         648 :              & d3etot_car(2,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)
    1093                 :             :              end if
    1094                 :             :            end do
    1095                 :             :          end do
    1096                 :          72 :          write(ab_out,*)' '
    1097                 :             :        end do
    1098                 :             :      end do
    1099                 :             :    end do
    1100                 :             : 
    1101                 :             : 
    1102                 :           3 :    write(ab_out,'(a)')' Clamped-ion elastic tensor, in cartesian coordinates '
    1103                 :           3 :    write(ab_out,'(a)')' (from sum rule of clamped-ion flexoelectric force-response tensor),'
    1104                 :           3 :    write(ab_out,'(a)')' (for stressed cells it lacks an improper contribution),'
    1105                 :           3 :    write(ab_out,'(a)')' atdir   qgrdir  strdir1  strdir2         real part          imaginary part'
    1106         [ +  + ]:          12 :    do i1dir=1,3
    1107         [ +  + ]:          30 :      do i3dir=1,i1dir
    1108         [ +  + ]:          54 :        do i2pert=natom+3, natom+4
    1109         [ +  + ]:         162 :          do i2dir=1,3
    1110                 :         108 :            istr=(i2pert-natom-3)*3+i2dir
    1111                 :         108 :            beta=idx(2*istr-1); delta=idx(2*istr)
    1112                 :         108 :            celastci=zero
    1113         [ +  + ]:         324 :            do i1pert=1,natom
    1114         [ +  - ]:         324 :              if (blkflg_car(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)==1) then
    1115                 :         216 :                celastci(1)=celastci(1)+d3etot_car(1,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)
    1116                 :         216 :                celastci(2)=celastci(2)+d3etot_car(2,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)
    1117                 :             :              end if
    1118                 :             :            end do
    1119                 :         108 :            write(ab_out,'(4(i5,3x),2(1x,f20.10))') i1dir,i3dir,beta,delta, &
    1120                 :         252 :          & celastci(1)/ucvol,celastci(2)/ucvol
    1121                 :             :          end do
    1122                 :             :        end do
    1123                 :          27 :        write(ab_out,*)' '
    1124                 :             :      end do
    1125                 :             :    end do
    1126                 :             :  end if
    1127                 :             : 
    1128         [ +  + ]:          17 :  if (lw_natopt==1) then
    1129                 :           1 :    write(ab_out,'(a)')' Natural optical activity tensor, in cartesian coordinates,'
    1130                 :           1 :    write(ab_out,'(a)')' (1/ucvol factor not included),'
    1131                 :           1 :    write(ab_out,'(a)')' efidir1   efidir2   qgrdir          real part          imaginary part'
    1132                 :           1 :    i1pert=natom+2
    1133                 :           1 :    i2pert=natom+2
    1134         [ +  + ]:           4 :    do i3dir=1,3
    1135         [ +  + ]:          12 :      do i1dir=1,3
    1136         [ +  + ]:          39 :        do i2dir=1,3
    1137         [ +  - ]:          36 :          if (blkflg_car(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)==1) then
    1138                 :          27 :            write(ab_out,'(3(i5,3x),2(1x,f20.10))') i1dir,i2dir,i3dir, &
    1139                 :          27 :          & -four*pi*d3etot_car(2,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert), &
    1140                 :          54 :          &  four*pi*d3etot_car(1,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)
    1141                 :             :          end if
    1142                 :             :        end do
    1143                 :             :      end do
    1144                 :           4 :      write(ab_out,*)' '
    1145                 :             :    end do
    1146                 :             :  end if
    1147                 :             : 
    1148         [ +  + ]:          17 :  if (timdisp==1) then
    1149                 :           6 :    i3pert=natom+9
    1150                 :           6 :    i3dir=1
    1151                 :           6 :    write(ab_out,'(a)')' Frequency derivative of second-order energies, in cartesian coordinates'
    1152                 :           6 :    write(ab_out,'(a)')'     j1       j2                    matrix elementi'
    1153                 :           6 :    write(ab_out,'(a)')'  dir pert dir pert           real part       imaginary part'
    1154         [ +  + ]:         128 :    do i1pert=1,mpert
    1155         [ +  + ]:         494 :      do i1dir=1,3
    1156         [ +  + ]:        8186 :        do i2pert=1,mpert
    1157         [ +  + ]:       31158 :          do i2dir=1,3
    1158         [ +  + ]:       30792 :            if (blkflg_car(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)==1) then
    1159                 :          30 :              write(ab_out,'(2(i4,i5),2(1x,f20.10))')i1dir,i1pert,i2dir,i2pert,&
    1160                 :          30 :            & d3etot_car(1,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert), &
    1161                 :          60 :            & d3etot_car(2,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)
    1162                 :             :            end if
    1163                 :             :          end do
    1164                 :             :        end do
    1165                 :             :      end do
    1166                 :             :    end do
    1167                 :             :  end if
    1168                 :             : 
    1169                 :             :  DBG_EXIT("COLL")
    1170                 :             : 
    1171                 :          17 : end subroutine dfptlw_out
    1172                 :             : !!***
    1173                 :             : 
    1174                 :             : end module m_longwave
    1175                 :             : !!***
        

Generated by: LCOV version 2.3-1