LCOV - code coverage report
Current view: top level - src/94_scfcv - m_elpolariz.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 12.3 % 373 46
Test Date: 2026-11-06 10:48:53 Functions: 33.3 % 3 1
Branches: 4.8 % 561 27

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_elpolariz
       2                 :             : !! NAME
       3                 :             : !! m_elpolariz
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!
       7                 :             : !!
       8                 :             : !! COPYRIGHT
       9                 :             : !!  Copyright (C) 2005-2026 ABINIT group (XG, NSAI, MKV)
      10                 :             : !!  This file is distributed under the terms of the
      11                 :             : !!  GNU General Public License, see ~abinit/COPYING
      12                 :             : !!  or http://www.gnu.org/copyleft/gpl.txt .
      13                 :             : !!
      14                 :             : !! SOURCE
      15                 :             : 
      16                 :             : #if defined HAVE_CONFIG_H
      17                 :             : #include "config.h"
      18                 :             : #endif
      19                 :             : 
      20                 :             : #include "abi_common.h"
      21                 :             : 
      22                 :             : module m_elpolariz
      23                 :             : 
      24                 :             :  use defs_basis
      25                 :             :  use m_abicore
      26                 :             :  use m_errors
      27                 :             :  use m_efield
      28                 :             :  use m_xmpi
      29                 :             :  use m_wffile
      30                 :             :  use m_hdr
      31                 :             :  use m_dtset
      32                 :             :  use m_dtfil
      33                 :             : 
      34                 :             :  use defs_datatypes,   only : pseudopotential_type
      35                 :             :  use defs_abitypes,    only : MPI_type
      36                 :             :  use m_geometry,       only : metric
      37                 :             :  use m_matrix,         only : matr3inv
      38                 :             :  use m_hide_lapack,    only : dzgedi, dzgefa
      39                 :             :  use m_rwwf,           only : rwwf
      40                 :             :  use m_pawtab,         only : pawtab_type
      41                 :             :  use m_pawrhoij,       only : pawrhoij_type
      42                 :             :  use m_pawcprj,        only : pawcprj_type
      43                 :             :  use m_berryphase,     only : berryphase
      44                 :             :  use m_berryphase_new, only : berryphase_new
      45                 :             : 
      46                 :             :  implicit none
      47                 :             : 
      48                 :             :  private
      49                 :             : !!***
      50                 :             : 
      51                 :             :  public :: elpolariz
      52                 :             : !!***
      53                 :             : 
      54                 :             : contains
      55                 :             : !!***
      56                 :             : 
      57                 :             : !!****f* ABINIT/elpolariz
      58                 :             : !! NAME
      59                 :             : !! elpolariz
      60                 :             : !!
      61                 :             : !! FUNCTION
      62                 :             : !! Calculate corrections to total energy from polarising
      63                 :             : !! electric field with or without Berry phases (berryopt keyword)
      64                 :             : !!
      65                 :             : !! INPUTS
      66                 :             : !! atindx1(natom)=index table for atoms, inverse of atindx (see gstate.f)
      67                 :             : !! cg(2,mcg)=planewave coefficients of wavefunctions
      68                 :             : !! cprj(natom,mcprj*usecprj)=<p_lmn|Cnk> coefficients for each WF |Cnk>
      69                 :             : !!                           and each |p_lmn> non-local projector
      70                 :             : !! dtfil <type(datafiles_type)>=variables related to files
      71                 :             : !! dtset <type(dataset_type)>=all input variables in this dataset
      72                 :             : !! gprimd(3,3)=reciprocal space dimensional primitive translations
      73                 :             : !! hdr <type(hdr_type)>=the header of wf, den and pot files
      74                 :             : !! kg(3,mpw*mkmem)=reduced planewave coordinates
      75                 :             : !! mband=maximum number of bands
      76                 :             : !! mcg=size of wave-functions array (cg) =mpw*nspinor*mband*mkmem*nsppol
      77                 :             : !! mkmem=number of k points treated by this node.
      78                 :             : !! mpi_enreg=information about MPI parallelization
      79                 :             : !! mpw=maximum dimensioned size of npw
      80                 :             : !! my_natom=number of atoms treated by current processor
      81                 :             : !! natom=number of atoms in cell
      82                 :             : !! nattyp(ntypat)= # atoms of each type.
      83                 :             : !! nkpt=number of k points
      84                 :             : !! npwarr(nkpt)=number of planewaves in basis at this k point
      85                 :             : !! nsppol=1 for unpolarized, 2 for spin-polarized
      86                 :             : !! ntypat=number of types of atoms in unit cell
      87                 :             : !! nkpt=number of k-points
      88                 :             : !! option = 1: compute Berryphase polarization
      89                 :             : !!          2: compute finite difference expression of the ddk
      90                 :             : !!          3: compute polarization & ddk
      91                 :             : !! pawrhoij(my_natom*usepaw) <type(pawrhoij_type)> atomic occupancies
      92                 :             : !! pawtab(dtset%ntypat) <type(pawtab_type)>=paw tabulated starting data
      93                 :             : !! pel_cg(3) = reduced coordinates of the electronic polarization (a. u.)
      94                 :             : !!             computed in the SCF loop
      95                 :             : !! pelev(3)= expectation value polarization term (PAW only) in cartesian coordinates
      96                 :             : !! psps <type(pseudopotential_type)>=variables related to pseudopotentials
      97                 :             : !! pwind(pwind_alloc,2,3) = array used to compute
      98                 :             : !!           the overlap matrix smat between k-points (see initberry.f)
      99                 :             : !! pwind_alloc = first dimension of pwind
     100                 :             : !! pwnsfac(2,pwind_alloc) = phase factors for non-symmorphic translations
     101                 :             : !! rprimd(3,3)=dimensional real space primitive translations (bohr)
     102                 :             : !! ucvol=unit cell volume in bohr**3.
     103                 :             : !! usecprj=1 if cprj datastructure has been allocated
     104                 :             : !! xred(3,natom)=reduced atomic coordinates
     105                 :             : !!
     106                 :             : !! OUTPUT
     107                 :             : !!  (see side effects)
     108                 :             : !!
     109                 :             : !! SIDE EFFECTS
     110                 :             : !! dtefield <type(efield_type)> = variables related to Berry phase
     111                 :             : !!       and electric field calculations (see initberry.f).
     112                 :             : !!       In case berryopt = 4/6/7/14/16/17, the overlap matrices computed
     113                 :             : !!       in this routine are stored in dtefield%smat in order
     114                 :             : !!       to be used in the electric field calculation.
     115                 :             : !! enefield=field energy
     116                 :             : !! etotal=total energy, might be correct by improved polarization computation
     117                 :             : !! pel(3) = reduced coordinates of the electronic polarization (a. u.)
     118                 :             : !! pion(3)= reduced coordinates of the ionic polarization (a. u.)
     119                 :             : !!
     120                 :             : !! SOURCE
     121                 :             : 
     122                 :          85 : subroutine elpolariz(atindx1,cg,cprj,dtefield,dtfil,dtset,etotal,enefield,gprimd,hdr,&
     123                 :          85 : & kg,mband,mcg,mcprj,mkmem,mpi_enreg,mpw,my_natom,natom,nattyp,nkpt,&
     124                 :          85 : & npwarr,nsppol,ntypat,pawrhoij,pawtab,&
     125                 :          85 : & pel,pel_cg,pelev,pion,psps,pwind,pwind_alloc,&
     126                 :          85 : & pwnsfac,rprimd,ucvol,usecprj,xred)
     127                 :             : 
     128                 :             : !Arguments ------------------------------------
     129                 :             : !scalars
     130                 :             :  integer,intent(in) :: mband,mcg,mcprj,mkmem,mpw,my_natom,natom,nkpt,nsppol,ntypat
     131                 :             :  integer,intent(in) :: pwind_alloc,usecprj
     132                 :             :  real(dp),intent(in) :: ucvol
     133                 :             :  real(dp),intent(inout) :: enefield,etotal
     134                 :             :  type(MPI_type),intent(in) :: mpi_enreg
     135                 :             :  type(datafiles_type),intent(in) :: dtfil
     136                 :             :  type(dataset_type),intent(inout) :: dtset
     137                 :             :  type(efield_type),intent(inout) :: dtefield
     138                 :             :  type(hdr_type),intent(inout) :: hdr
     139                 :             :  type(pseudopotential_type),intent(in) :: psps
     140                 :             : !arrays
     141                 :             :  integer,intent(in) :: atindx1(natom),kg(3,mpw*mkmem),nattyp(ntypat)
     142                 :             :  integer,intent(in) :: npwarr(nkpt),pwind(pwind_alloc,2,3)
     143                 :             :  real(dp),intent(in) :: cg(2,mcg),gprimd(3,3)
     144                 :             :  real(dp),intent(in) :: pel_cg(3),pwnsfac(2,pwind_alloc),rprimd(3,3)
     145                 :             :  real(dp),intent(inout) :: pel(3),pelev(3),pion(3),xred(3,natom)
     146                 :             :  type(pawcprj_type),intent(in) :: cprj(natom,mcprj*usecprj)
     147                 :             :  type(pawrhoij_type), intent(in) :: pawrhoij(my_natom*psps%usepaw)
     148                 :             :  type(pawtab_type),intent(in) :: pawtab(dtset%ntypat*psps%usepaw)
     149                 :             : 
     150                 :             : !Local variables-------------------------------
     151                 :             : !scalars
     152                 :             :  integer :: mcg1_3,my_nspinor,option,unit_out,iir,jjr,kkr
     153                 :             :  real(dp) :: pdif_mod,eenth,ucvol_local
     154                 :             :  logical :: save_cg1_3
     155                 :             :  character(len=500) :: message
     156                 :             : !arrays
     157                 :             :  real(dp) :: gmet(3,3),gprimdlc(3,3),pdif(3),ptot(3),red_ptot(3),rmet(3,3)
     158                 :             : !! ptot(3) = total polarization (not reduced) REC
     159                 :             : !! red_ptot(3) = internal reduced total polarization REC
     160                 :             :  real(dp) ::  A(3,3),A1(3,3),A_new(3,3),efield_new(3)
     161                 :          85 :  real(dp),allocatable :: cg1_3(:,:,:)
     162                 :             : 
     163                 :             : ! *************************************************************************
     164                 :             : 
     165                 :             :  DBG_ENTER("COLL")
     166                 :             : 
     167   [ +  +  -  + ]:          85 :  if (usecprj==0.and.psps%usepaw==1) then
     168                 :             :    write (message,'(3a)')&
     169                 :           0 : &   'cprj datastructure must be allocated !',ch10,&
     170                 :           0 : &   'Action: change pawusecp input keyword.'
     171                 :           0 :    ABI_ERROR(message)
     172                 :             :  end if
     173                 :             : 
     174                 :          85 :  my_nspinor=max(1,dtset%nspinor/mpi_enreg%nproc_spinor)
     175                 :             : 
     176                 :             :  if(dtset%berryopt>0 .and. dtset%berryopt/=4 .and. dtset%berryopt/=6 .and. dtset%berryopt/=7 .and. &
     177         [ -  + ]:          85 : & dtset%berryopt/=14 .and. dtset%berryopt/=16 .and. dtset%berryopt/=17)then  !!HONG
     178                 :             : 
     179                 :             :    if (dtset%berryopt==1 .or. dtset%berryopt==3) then
     180                 :             :      call berryphase(atindx1,dtset%bdberry,cg,gprimd,dtset%istwfk,&
     181                 :             : &     dtset%kberry,kg,dtset%kptns,dtset%kptopt,dtset%kptrlatt,&
     182                 :             : &     mband,mcg,mkmem,mpw,natom,nattyp,dtset%nband,dtset%nberry,npwarr,&
     183                 :             : &     my_nspinor,nsppol,psps%ntypat,nkpt,rprimd,ucvol,&
     184                 :           0 : &     xred,psps%ziontypat)
     185                 :             :    end if
     186                 :             : 
     187         [ #  # ]:           0 :    if (dtset%berryopt==2 .or. dtset%berryopt==3) then
     188                 :             :      call uderiv(dtset%bdberry,cg,gprimd,hdr,dtset%istwfk,&
     189                 :             : &     dtset%kberry,kg,dtset%kptns,dtset%kptopt,&
     190                 :             : &     dtset%kptrlatt,mband,mcg,mkmem,mpi_enreg,mpw,&
     191                 :             : &     natom,dtset%nband,dtset%nberry,npwarr,my_nspinor,nsppol,&
     192                 :           0 : &     nkpt,dtfil%unddk,dtfil%fnameabo_1wf)
     193                 :             :    end if
     194                 :             : 
     195                 :             :  else if(dtset%berryopt<0 .or. dtset%berryopt==4 .or. dtset%berryopt==6 .or. dtset%berryopt==7 .or.  &
     196         [ -  + ]:          85 : &   dtset%berryopt==14 .or. dtset%berryopt==16 .or. dtset%berryopt==17)then   !!HONG
     197                 :             : 
     198                 :           0 :    select case (dtset%berryopt)
     199                 :             :    case (-5)
     200                 :           0 :      option = 2
     201                 :             :    case (-3)
     202                 :           1 :      option = 3
     203                 :             :    case (-2)
     204                 :           3 :      option = 2
     205                 :             :    case (-1)
     206                 :          56 :      option = 1
     207                 :             :    case (4)
     208                 :          25 :      option = 1
     209                 :          25 :      pel(:) = zero
     210                 :          25 :      pelev(:) = zero
     211                 :             :    case (6)                !!HONG
     212                 :           0 :      option = 1
     213                 :           0 :      pel(:) = zero
     214                 :           0 :      pelev(:) = zero
     215                 :             :    case (7)                !!HONG
     216                 :           0 :      option = 1
     217                 :           0 :      pel(:) = zero
     218                 :           0 :      pelev(:) = zero
     219                 :             :    case (14)                !!HONG
     220                 :           0 :      option = 1
     221                 :           0 :      pel(:) = zero
     222                 :           0 :      pelev(:) = zero
     223                 :             :    case (16)                !!HONG
     224                 :           0 :      option = 1
     225                 :           0 :      pel(:) = zero
     226                 :           0 :      pelev(:) = zero
     227                 :             :    case (17)                !!HONG
     228                 :           0 :      option = 1
     229                 :           0 :      pel(:) = zero
     230   [ -  +  +  +  :          85 :      pelev(:) = zero
          +  -  -  -  -  
                   -  - ]
     231                 :             :    end select
     232                 :             : 
     233                 :          85 :    unit_out = ab_out
     234                 :             : 
     235                 :             :    ! by default berryphase_new writes ddk wavefunctions to disk
     236                 :             :    ! with save_cg1_3 set to true it can return them in memory
     237                 :             :    ! this feature is used at present when orbmag is also called,
     238                 :             :    ! as in afterscfloop
     239                 :          85 :    save_cg1_3 = .FALSE.
     240                 :          85 :    mcg1_3 = 0
     241         [ -  + ]:          85 :    ABI_MALLOC(cg1_3,(2,mcg1_3,3))
     242                 :             :    call berryphase_new(atindx1,cg,cg1_3,cprj,dtefield,dtfil,dtset,psps,&
     243                 :             : &   gprimd,hdr,psps%indlmn,kg,&
     244                 :             : &   psps%lmnmax,mband,mcg,mcg1_3,mcprj,mkmem,mpi_enreg,mpw,my_natom,natom,npwarr,&
     245                 :             : &   nsppol,psps%ntypat,nkpt,option,pawrhoij,&
     246                 :             : &   pawtab,pel,pelev,pion,ptot,red_ptot,pwind,&                            !!REC
     247                 :             : &  pwind_alloc,pwnsfac,rprimd,save_cg1_3,dtset%typat,ucvol,&
     248                 :          85 : &   unit_out,usecprj,psps%usepaw,xred,psps%ziontypat)
     249         [ -  + ]:          85 :    ABI_FREE(cg1_3)
     250                 :             : 
     251         [ +  + ]:         340 :    dtefield%red_ptot1(:)=red_ptot(:)
     252                 :             : 
     253                 :             :    if (dtset%berryopt == 4 .or. dtset%berryopt == 6 .or. dtset%berryopt == 7 .or.  &
     254         [ +  + ]:          85 : &   dtset%berryopt == 14 .or. dtset%berryopt == 16 .or. dtset%berryopt == 17 ) then   !!HONG
     255                 :             : 
     256                 :             : !    Check if pel has the same value as pel_cg
     257                 :             : !    if (psps%usepaw == 1) pel(:) = pel(:) + pelev(:) ! add on-site term for PAW
     258                 :             : !    if (psps%usepaw == 1) red_ptot(:) = red_ptot(:) + pelev(:) ! add on-site term for PAW  !! REC
     259                 :             : !    above line suppressed because in the PAW case, pel already includes all on-site
     260                 :             : !    terms and pelev should not be added in additionally. We are computing pelev separately for
     261                 :             : !    reporting purposes only.
     262                 :             : !    13 June 2012 J Zwanziger
     263                 :             : 
     264         [ +  + ]:         100 :      pdif(:) = pel_cg(:) - pel(:)
     265                 :          25 :      pdif_mod = pdif(1)**2 + pdif(2)**2 + pdif(3)**2
     266                 :             : 
     267         [ -  + ]:          25 :      if (pdif_mod > tol8) then
     268                 :           0 :        write(message,'(11(a),e16.9)')ch10,&
     269                 :           0 : &       ' scfcv (electric field calculation) : WARNING -',ch10,&
     270                 :           0 : &       '   The difference between pel (electronic Berry phase updated ',ch10,&
     271                 :           0 : &       '   at each SCF cycle)',ch10,&
     272                 :           0 : &       '   and pel_cg (electronic Berryphase computed using the ',&
     273                 :           0 : &       'berryphase routine) is',ch10,&
     274                 :           0 : &       '   pdif_mod = ',pdif_mod
     275                 :           0 :        call wrtout(std_out,message,'COLL')
     276                 :           0 :        write(message,'(a,6(a,e16.9,a))') ch10,&
     277                 :           0 : &       'pel_cg(1) = ',pel_cg(1),ch10,&
     278                 :           0 : &       'pel_cg(2) = ',pel_cg(2),ch10,&
     279                 :           0 : &       'pel_cg(3) = ',pel_cg(3),ch10,&
     280                 :           0 : &       'pel(1) = ',pel(1),ch10,&
     281                 :           0 : &       'pel(2) = ',pel(2),ch10,&
     282                 :           0 : &       'pel(3) = ',pel(3),ch10
     283                 :           0 :        ABI_ERROR(message)
     284                 :             :      end if
     285                 :             : 
     286                 :             : !    Use this (more accurate) value of P to recompute enefield
     287         [ +  - ]:          25 :      if (dtset%berryopt == 4 .or. dtset%berryopt == 14 ) then             !!HONG
     288                 :          25 :        etotal = etotal - enefield
     289                 :             : 
     290         [ +  + ]:         100 :        enefield = -dot_product(dtset%red_efieldbar,red_ptot)
     291                 :          25 :        call metric(gmet,gprimdlc,-1,rmet,rprimd,ucvol_local)
     292                 :          25 :        eenth = zero
     293         [ +  + ]:         100 :        do iir=1,3
     294         [ +  + ]:         325 :          do jjr=1,3
     295                 :         300 :            eenth= eenth+gmet(iir,jjr)*dtset%red_efieldbar(iir)*dtset%red_efieldbar(jjr)         !! HONG g^{-1})_ij ebar_i ebar_j
     296                 :             :          end do
     297                 :             :        end do
     298                 :          25 :        eenth=-1_dp*(ucvol_local/(8.0d0*pi))*eenth
     299                 :          25 :        enefield=enefield+eenth
     300                 :             : 
     301                 :          25 :        etotal = etotal + enefield
     302                 :             : 
     303                 :          25 :        write(message,'(a,a)')ch10,&
     304                 :          50 : &       ' Stress tensor under a constant electric field:'
     305                 :          25 :        call wrtout(std_out,message,'COLL')
     306                 :          25 :        call wrtout(ab_out,message,'COLL')
     307                 :             : 
     308                 :             :      end if
     309                 :             : 
     310                 :             : !    ! In finite D-field case, turn it into internal energy    !!HONG
     311         [ -  + ]:          25 :      if (dtset%berryopt == 6 .or. dtset%berryopt == 16 )  then
     312                 :           0 :        etotal = etotal - enefield
     313                 :             : 
     314                 :           0 :        enefield=zero
     315                 :           0 :        call metric(gmet,gprimdlc,-1,rmet,rprimd,ucvol_local)
     316         [ #  # ]:           0 :        do iir=1,3
     317         [ #  # ]:           0 :          do jjr=1,3
     318                 :           0 :            enefield= enefield+gmet(iir,jjr)*dtset%red_efieldbar(iir)*dtset%red_efieldbar(jjr)         !! HONG g^{-1})_ij ebar_i ebar_j
     319                 :             :          end do
     320                 :             :        end do
     321                 :           0 :        enefield= ucvol_local/(8.0d0*pi)*enefield
     322                 :             : 
     323                 :           0 :        etotal = etotal + enefield
     324                 :             : 
     325                 :           0 :        write(message,'(a,a)')ch10,&
     326                 :           0 : &       ' Stress tensor under a constant electric displacement field:'
     327                 :           0 :        call wrtout(std_out,message,'COLL')
     328                 :           0 :        call wrtout(ab_out,message,'COLL')
     329                 :             : 
     330                 :             :      end if
     331                 :             : 
     332                 :             : !    HONG  calculate internal energy and electric enthalpy for mixed BC case.
     333         [ -  + ]:          25 :      if ( dtset%berryopt == 17 ) then
     334                 :           0 :        etotal = etotal - enefield
     335                 :           0 :        enefield = zero
     336                 :             : 
     337                 :           0 :        call metric(gmet,gprimdlc,-1,rmet,rprimd,ucvol_local)
     338   [ #  #  #  # ]:           0 :        A(:,:)=(4*pi/ucvol_local)*rmet(:,:)
     339                 :           0 :        A1(:,:)=A(:,:)
     340                 :           0 :        A_new(:,:)=A(:,:)
     341         [ #  # ]:           0 :        efield_new(:)=dtset%red_efield(:)
     342                 :             :        eenth = zero
     343                 :             : 
     344         [ #  # ]:           0 :        do kkr=1,3
     345         [ #  # ]:           0 :          if (dtset%jfielddir(kkr)==1) then    ! fixed ebar direction
     346                 :             : !          step 1 add -ebar*p
     347                 :           0 :            eenth=eenth - dtset%red_efieldbar(kkr)*red_ptot(kkr)
     348                 :             : 
     349                 :             : !          step 2  chang to e_new (change e to ebar)
     350                 :           0 :            efield_new(kkr)=dtset%red_efieldbar(kkr)
     351                 :             : 
     352                 :             : !          step 3  chang matrix A to A1
     353                 :             : 
     354         [ #  # ]:           0 :            do iir=1,3
     355         [ #  # ]:           0 :              do jjr=1,3
     356         [ #  # ]:           0 :                if (iir==kkr .and. jjr==kkr) A1(iir,jjr)=-1.0/A(kkr,kkr)
     357         [ #  # ]:           0 :                if ((iir==kkr .and. jjr/=kkr) .or.  (iir/=kkr .and.  jjr==kkr)) &
     358                 :           0 : &               A1(iir,jjr)=-1.0*A(iir,jjr)/A(kkr,kkr)
     359         [ #  # ]:           0 :                if (iir/=kkr .and. jjr/=kkr) A1(iir,jjr)=A(iir,jjr)-A(iir,kkr)*A(kkr,jjr)/A(kkr,kkr)
     360                 :             :              end do
     361                 :             :            end do
     362                 :             : 
     363                 :           0 :            A(:,:)=A1(:,:)
     364                 :           0 :            A_new(:,:)=A1(:,:)
     365                 :             :          end if
     366                 :             : 
     367                 :             :        end do  ! end fo kkr
     368                 :             : 
     369                 :             : 
     370         [ #  # ]:           0 :        do iir=1,3
     371         [ #  # ]:           0 :          do jjr=1,3
     372                 :           0 :            eenth= eenth+(1/2.0)*A_new(iir,jjr)*efield_new(iir)*efield_new(jjr)
     373                 :             :          end do
     374                 :             :        end do
     375                 :             : 
     376                 :           0 :        enefield=eenth
     377                 :           0 :        etotal = etotal + enefield
     378                 :             : 
     379                 :           0 :        write(message,'(a,a)')ch10,&
     380                 :           0 : &       ' Stress tensor under a constant (mixed) electric and electric displacement field:'
     381                 :           0 :        call wrtout(std_out,message,'COLL')
     382                 :           0 :        call wrtout(ab_out,message,'COLL')
     383                 :             : 
     384                 :             :      end if   ! berryopt==17
     385                 :             : 
     386                 :             : 
     387                 :             : !    MVeithen: to clarify
     388                 :             : !    Which stress tensor should be used in structural optimizations?
     389                 :             : !    The one at constant electric field or at constant potential drop.
     390                 :             : !    write(message,'(a,a)')ch10,&
     391                 :             : !    &     ' Stress tensor imposing a constant electric field:'
     392                 :             : !    call wrtout(std_out,message,'COLL')
     393                 :             : !    call wrtout(ab_out,message,'COLL')
     394                 :             : 
     395                 :             :    end if ! dtset%berryopt == 4/6/7/14/16/17
     396                 :             : 
     397                 :             :  end if ! dtset%berryopt>0 or dtset%berryopt/=4/6/7/14/16/17
     398                 :             : 
     399                 :             :  DBG_EXIT("COLL")
     400                 :             : 
     401                 :          85 : end subroutine elpolariz
     402                 :             : !!***
     403                 :             : 
     404                 :             : !!****f* ABINIT/uderiv
     405                 :             : !! NAME
     406                 :             : !! uderiv
     407                 :             : !!
     408                 :             : !! FUNCTION
     409                 :             : !! This routine is called computes the derivative of
     410                 :             : !! ground-state wavefunctions with respect to k (du/dk) by finite differencing
     411                 :             : !! on neighbouring k points
     412                 :             : !! Work for nsppol=1 or 2, but only accept nspinor=1,
     413                 :             : !!
     414                 :             : !! INPUTS
     415                 :             : !!  bdberry(4)=band limits for Berry phase contributions (or du/dk)
     416                 :             : !!   spin up and spin down (bdberry(3:4) is irrelevant when nsppol=1)
     417                 :             : !!  cg(2,mcg)=planewave coefficients of wavefunctions
     418                 :             : !!  gprimd(3,3)=reciprocal space dimensional primitive translations
     419                 :             : !!  hdr <type(hdr_type)>=the header of wf, den and pot files
     420                 :             : !!  istwfk(nkpt_)=input option parameter that describes the storage of wfs
     421                 :             : !!  kberry(3,20)= different delta k for Berry phases(or du/dk),
     422                 :             : !!   in unit of kptrlatt only kberry(1:3,1:nberry) is relevant
     423                 :             : !!  kg(3,mpw*mkmem)=reduced planewave coordinates
     424                 :             : !!  kpt_(3,nkpt_)=reduced coordinates of k points generated by ABINIT,
     425                 :             : !!               kpt_ samples half the BZ if time-reversal symetrie is used
     426                 :             : !!  kptopt=2 when time-reversal symmetry is used
     427                 :             : !!  kptrlatt(3,3)=k-point lattice specification
     428                 :             : !!  mband=maximum number of bands
     429                 :             : !!  mcg=size of wave-functions array (cg) =mpw*nspinor*mband*mkmem*nsppol
     430                 :             : !!  mkmem=number of k points treated by this node.
     431                 :             : !!  mpi_enreg=information about MPI parallelization
     432                 :             : !!  mpw=maximum dimensioned size of npw
     433                 :             : !!  natom=number of atoms in cell
     434                 :             : !!  nband(nkpt*nsppol)=number of bands at each k point, for each polarization
     435                 :             : !!  nberry=number of Berry phases(or du/dk) to be computed
     436                 :             : !!  nkpt=number of k points
     437                 :             : !!  npwarr(nkpt)=number of planewaves in basis at this k point
     438                 :             : !!  nspinor=number of spinorial components of the wavefunctions (on current proc)
     439                 :             : !!  nsppol=1 for unpolarized, 2 for spin-polarized
     440                 :             : !!  unddk=unit number for ddk file
     441                 :             : !!
     442                 :             : !! OUTPUT
     443                 :             : !!  (the ddk wavefunctions are written on disk)
     444                 :             : !!
     445                 :             : !! SIDE EFFECTS
     446                 :             : !!
     447                 :             : !! TODO
     448                 :             : !!  Cleaning, checking for rules
     449                 :             : !!  Should allow for time-reversal symmetry (istwfk)
     450                 :             : !!  WARNING : the use of nspinor is completely erroneous
     451                 :             : !!
     452                 :             : !! NOTES
     453                 :             : !! Local Variables:
     454                 :             : !!  cmatrix(:,:,:)= overlap matrix of size maxband*maxband
     455                 :             : !!  cg_index(:,:,:)= unpacked cg index array for specific band,
     456                 :             : !!   k point and polarization.
     457                 :             : !!  det(2,2)= intermediate output of Lapack routine zgedi.f
     458                 :             : !!  dk(3)= step taken to the next k mesh point along the kberry direction
     459                 :             : !!  gpard(3)= dimensionalreciprocal lattice vector G along which the
     460                 :             : !!          polarization is computed
     461                 :             : !!  kg_kpt(:,:,:)= unpacked reduced planewave coordinates with subscript of
     462                 :             : !!          planewave and k point
     463                 :             : !!  kpt(3,nkpt)=reduced coordinates of k-point grid that samples the whole BZ
     464                 :             : !!  kpt_flag(nkpt)=kpt_flag(ikpt)=0 when the wf was generated by the ABINIT
     465                 :             : !!                 code
     466                 :             : !!                 kpt_flag(ikpt) gives the indices of the k-point
     467                 :             : !!                 related to ikpt by time revers
     468                 :             : !!  maxband/minband= control the minimum and maximum band calculated in the
     469                 :             : !!           overlap matrix
     470                 :             : !!  npw_k= npwarr(ikpt), number of planewaves in basis at this k point
     471                 :             : !!  shift_g_2(nkpt,nkpt)= .true. if the k point should be shifted by a G vector;
     472                 :             : !!  .false. if not
     473                 :             : !!  tr(2)=variable that changes k to -k
     474                 :             : !!                              G to -G
     475                 :             : !!                     $c_g$ to $c_g^*$ when time-reversal symetrie is used
     476                 :             : !!
     477                 :             : !! SOURCE
     478                 :             : 
     479                 :           0 : subroutine uderiv(bdberry,cg,gprimd,hdr,istwfk,kberry,kg,kpt_,kptopt,kptrlatt,&
     480                 :           0 : & mband,mcg,mkmem,mpi_enreg,mpw,natom,nband,nberry,npwarr,nspinor,nsppol,nkpt_,&
     481                 :             : & unddk,fnameabo_1wf)
     482                 :             : 
     483                 :             : !Arguments ------------------------------------
     484                 :             : !scalars
     485                 :             :  integer,intent(in) :: kptopt,mband,mcg,mkmem,mpw,natom,nberry,nkpt_,nspinor
     486                 :             :  integer,intent(in) :: nsppol,unddk
     487                 :             :  type(MPI_type),intent(in) :: mpi_enreg
     488                 :             :  type(hdr_type),intent(inout) :: hdr
     489                 :             : !arrays
     490                 :             :  integer,intent(in) :: bdberry(4),istwfk(nkpt_),kberry(3,20),kg(3,mpw*mkmem)
     491                 :             :  integer,intent(in) :: kptrlatt(3,3),nband(nkpt_*nsppol),npwarr(nkpt_)
     492                 :             :  real(dp),intent(in) :: cg(2,mcg),gprimd(1:3,1:3)
     493                 :             :  real(dp),intent(in) :: kpt_(3,nkpt_)
     494                 :             :  character(len=fnlen),intent(in) :: fnameabo_1wf
     495                 :             : 
     496                 :             : !Local variables -------------------------
     497                 :             : !scalars
     498                 :             :  integer,parameter :: master=0
     499                 :             :  integer :: iomode,band_in,cg_index_iband,fform,flag1
     500                 :             :  integer :: formeig,iband,iberry,icg,idir,ierr,ifor,ii,ikpt,ikpt2,ikpt_
     501                 :             :  integer :: index,index1,info,ipert,ipw,isgn,isppol,jband,jj,jkpt,jkpt_
     502                 :             :  integer :: maxband,mcg_disk,me,minband,nband_diff,nband_k
     503                 :             :  integer :: nkpt,npw_k,pertcase,rdwr,read_k,spaceComm
     504                 :             :  integer :: tim_rwwf
     505                 :             :  real(dp) :: gmod,twodk
     506                 :             :  character(len=500) :: message
     507                 :             :  character(len=fnlen) :: fiwf1o
     508                 :             :  type(wffile_type) :: wffddk
     509                 :             : !arrays
     510                 :           0 :  integer :: kg_jl(0,0,0),kpt_flag(2*nkpt_)
     511                 :           0 :  integer,allocatable :: cg_index(:,:,:),ikpt_dk(:,:),ipvt(:)
     512                 :           0 :  integer,allocatable :: kg_kpt(:,:,:)
     513                 :             :  real(dp) :: det(2,2),diffk(3),diffk2(3),dk(3),gpard(3),klattice(3,3)
     514                 :             :  real(dp) :: kptrlattr(3,3),tr(2)
     515                 :             :  real(dp) :: cg_disk(0,0,0)
     516                 :           0 :  real(dp),allocatable :: cmatrix(:,:,:),dudk(:,:)
     517                 :           0 :  real(dp),allocatable :: eig_dum_2(:),kpt(:,:)
     518                 :           0 :  real(dp),allocatable :: occ_dum_2(:),phi(:,:,:),u_tilde(:,:,:,:),zgwork(:,:)
     519                 :           0 :  logical,allocatable :: shift_g_2(:,:)
     520                 :             : 
     521                 :             : ! *************************************************************************
     522                 :             : 
     523         [ #  # ]:           0 :  if(min(2,(1+mpi_enreg%paral_spinor)*nspinor)==2)then
     524                 :           0 :    ABI_ERROR('uderiv: does not yet work for nspinor=2')
     525                 :             :  end if
     526                 :             : 
     527   [ #  #  #  # ]:           0 :  if(maxval(istwfk(:))/=1)then
     528                 :             :    write(message,'(3a)')&
     529                 :           0 : &   'Sorry, this routine does not work yet with istwfk/=1.',ch10,&
     530                 :           0 : &   'This should have been tested previously ...'
     531                 :           0 :    ABI_BUG(message)
     532                 :             :  end if
     533                 :             : 
     534         [ #  # ]:           0 :  if (kptopt==3) then
     535                 :           0 :    nkpt = nkpt_
     536   [ #  #  #  #  :           0 :    ABI_MALLOC(kpt,(3,nkpt))
          #  #  #  #  #  
                #  #  # ]
     537   [ #  #  #  # ]:           0 :    kpt(:,:)=kpt_(:,:)
     538         [ #  # ]:           0 :  else if (kptopt==2) then
     539                 :           0 :    nkpt = nkpt_*2
     540   [ #  #  #  #  :           0 :    ABI_MALLOC(kpt,(3,nkpt))
          #  #  #  #  #  
                #  #  # ]
     541         [ #  # ]:           0 :    do ikpt = 1,nkpt/2
     542                 :           0 :      kpt_flag(ikpt) = 0
     543         [ #  # ]:           0 :      kpt(:,ikpt)=kpt_(:,ikpt)
     544                 :             :    end do
     545                 :           0 :    index = 0
     546         [ #  # ]:           0 :    do ikpt = (nkpt/2+1),nkpt
     547                 :           0 :      flag1 = 0
     548         [ #  # ]:           0 :      do jkpt = 1, nkpt/2
     549                 :             :        if (((abs(kpt_(1,ikpt-nkpt/2)+kpt_(1,jkpt))<1.0d-8).or.&
     550                 :             : &       (abs(1-abs(kpt_(1,ikpt-nkpt/2)+kpt_(1,jkpt)))<1.0d-8))&
     551                 :             : &       .and.((abs(kpt_(2,ikpt-nkpt/2)+kpt_(2,jkpt))<1.0d-8).or.&
     552                 :             : &       (abs(1-abs(kpt_(2,ikpt-nkpt/2)+kpt_(2,jkpt)))<1.0d-8))&
     553   [ #  #  #  #  :           0 : &       .and.((abs(kpt_(3,ikpt-nkpt/2)+kpt_(3,jkpt))<1.0d-8).or.&
          #  #  #  #  #  
                      # ]
     554         [ #  # ]:           0 : &       (abs(1-abs(kpt_(3,ikpt-nkpt/2)+kpt_(3,jkpt)))<1.0d-8))) then
     555                 :           0 :          flag1 = 1
     556                 :           0 :          index = index + 1
     557                 :             :          exit
     558                 :             :        end if
     559                 :             :      end do
     560                 :           0 :      if (flag1==0) then
     561                 :           0 :        kpt_flag(ikpt-index)=ikpt-nkpt/2
     562         [ #  # ]:           0 :        kpt(:,ikpt-index)=-kpt_(:,ikpt-nkpt/2)
     563                 :             :      end if
     564                 :             :    end do
     565                 :           0 :    nkpt = nkpt - index
     566                 :             :  end if
     567                 :             : 
     568                 :             : !DEBUG
     569                 :             : !write(101,*) 'beginning write kpt'
     570                 :             : !do ikpt=1,nkpt
     571                 :             : !write(101,*) kpt(:,ikpt)
     572                 :             : !end do
     573                 :             : !ENDDEBUG
     574                 :             : 
     575   [ #  #  #  #  :           0 :  ABI_MALLOC(shift_g_2,(nkpt,nkpt))
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     576                 :             : 
     577                 :             : !Compute primitive vectors of the k point lattice
     578                 :             : !Copy to real(dp)
     579   [ #  #  #  # ]:           0 :  kptrlattr(:,:)=kptrlatt(:,:)
     580                 :             : !Go to reciprocal space (in reduced coordinates)
     581                 :           0 :  call matr3inv(kptrlattr,klattice)
     582                 :             : 
     583         [ #  # ]:           0 :  do iberry=1,nberry
     584                 :             : 
     585                 :             : !  **************************************************************************
     586                 :             : !  Determine the appended index for ddk 1WF files
     587                 :             : 
     588         [ #  # ]:           0 :    do idir=1,3
     589         [ #  # ]:           0 :      if (kberry(idir,iberry) ==1) then
     590                 :           0 :        ipert=natom+1
     591                 :           0 :        pertcase=idir+(ipert-1)*3
     592                 :             :      end if
     593                 :             :    end do
     594                 :             : 
     595                 :             : !  open ddk 1WF file
     596                 :           0 :    formeig=1
     597                 :             : 
     598                 :           0 :    call appdig(pertcase,fnameabo_1wf,fiwf1o)
     599                 :             :    !call wfk_open_read(wfk, fiwf1o, formeig, iomode, unddk, spaceComm)
     600                 :             : 
     601                 :           0 :    spaceComm=xmpi_comm_self; me=0 ; iomode=IO_MODE_FORTRAN
     602                 :           0 :    call WffOpen(iomode,spaceComm,fiwf1o,ierr,wffddk,master,me,unddk)
     603                 :             : 
     604                 :           0 :    rdwr=2 ; fform=2
     605                 :           0 :    call hdr_io(fform,hdr,rdwr,wffddk)
     606                 :             : 
     607                 :             : !  Define offsets, in case of MPI I/O
     608                 :           0 :    call xdefineOff(formeig,wffddk,mpi_enreg,nband,npwarr,nspinor,nsppol,nkpt_)
     609                 :             : 
     610                 :             : !  *****************************************************************************
     611                 :             : !  Calculate dimensional recip lattice vector along which P is calculated
     612                 :             : !  dk =  step to the nearest k point along that direction
     613                 :             : !  in reduced coordinates
     614                 :             : 
     615                 :             :    dk(:)=dble(kberry(1,iberry))*klattice(:,1)+&
     616                 :             : &   dble(kberry(2,iberry))*klattice(:,2)+&
     617         [ #  # ]:           0 : &   dble(kberry(3,iberry))*klattice(:,3)
     618                 :             : 
     619         [ #  # ]:           0 :    do idir=1,3
     620         [ #  # ]:           0 :      if (dk(idir)/=0) then
     621                 :           0 :        twodk=2*dk(idir)
     622                 :             :      end if
     623                 :             :    end do
     624                 :             : 
     625         [ #  # ]:           0 :    gpard(:)=dk(1)*gprimd(:,1)+dk(2)*gprimd(:,2)+dk(3)*gprimd(:,3)
     626                 :             :    gmod=sqrt(dot_product(gpard,gpard))
     627                 :             : 
     628                 :             : !  ******************************************************************************
     629                 :             : !  Select the k grid  points along the direction to compute dudk
     630                 :             : !  dk =  step to the nearest k point along that direction
     631                 :             : 
     632                 :             : !  For each k point, find k_prim such that k_prim= k + dk mod(G)
     633                 :             : !  where G is a vector of the reciprocal lattice
     634   [ #  #  #  #  :           0 :    ABI_MALLOC(ikpt_dk,(2,nkpt))
          #  #  #  #  #  
                #  #  # ]
     635   [ #  #  #  # ]:           0 :    ikpt_dk(1:2,1:nkpt)=0
     636   [ #  #  #  # ]:           0 :    shift_g_2(:,:)= .false.
     637                 :             : 
     638         [ #  # ]:           0 :    do ikpt=1,nkpt
     639         [ #  # ]:           0 :      do ikpt2=1,nkpt
     640         [ #  # ]:           0 :        diffk(:)=abs(kpt(:,ikpt2)-kpt(:,ikpt)-dk(:))
     641         [ #  # ]:           0 :        diffk2(:)=abs(kpt(:,ikpt2)-kpt(:,ikpt)+dk(:))
     642   [ #  #  #  # ]:           0 :        if (sum(abs(diffk(:)-nint(diffk(:))))<3*tol8)then
     643                 :           0 :          ikpt_dk(1,ikpt)=ikpt2
     644   [ #  #  #  # ]:           0 :          if(sum(diffk(:))>=3*tol8) shift_g_2(ikpt,ikpt2) = .true.
     645                 :             :        end if
     646   [ #  #  #  # ]:           0 :        if (sum(abs(diffk2(:)-nint(diffk2(:))))<3*tol8)then
     647                 :           0 :          ikpt_dk(2,ikpt)=ikpt2
     648   [ #  #  #  # ]:           0 :          if(sum(diffk2(:))>=3*tol8) shift_g_2(ikpt,ikpt2) = .true.
     649                 :             :        end if
     650                 :             :      end do
     651                 :             :    end do
     652                 :             : 
     653                 :           0 :    write(message,'(a,a,a,3f9.5,a,a,3f9.5,a)')ch10,&
     654                 :           0 : &   ' Computing the derivative for reciprocal vector:',ch10,&
     655                 :           0 : &   dk(:),' (in reduced coordinates)',ch10,&
     656                 :           0 : &   gpard(1:3),' (in cartesian coordinates - atomic units)'
     657                 :           0 :    call wrtout(ab_out,message,'COLL')
     658                 :           0 :    call wrtout(std_out,message,'COLL')
     659                 :             : 
     660         [ #  # ]:           0 :    if(nsppol==1)then
     661                 :             :      write(message, '(a,i5,a,i5)')&
     662                 :           0 : &     ' From band number',bdberry(1),'  to band number',bdberry(2)
     663                 :             :    else
     664                 :             :      write(message, '(a,i5,a,i5,a,a,a,i5,a,i5,a)')&
     665                 :           0 : &     ' From band number',bdberry(1),'  to band number',bdberry(2),' for spin up,',&
     666                 :           0 : &     ch10,&
     667                 :           0 : &     ' from band number',bdberry(3),'  to band number',bdberry(4),' for spin down.'
     668                 :             :    end if
     669                 :           0 :    call wrtout(ab_out,message,'COLL')
     670                 :           0 :    call wrtout(std_out,message,'COLL')
     671                 :             : 
     672                 :             : !  *****************************************************************************
     673   [ #  #  #  #  :           0 :    ABI_MALLOC(dudk,(2,mpw*nspinor*mband*nsppol))
          #  #  #  #  #  
                #  #  # ]
     674   [ #  #  #  #  :           0 :    ABI_MALLOC(eig_dum_2,((2*mband)**formeig*mband))
          #  #  #  #  #  
                #  #  # ]
     675   [ #  #  #  #  :           0 :    ABI_MALLOC(occ_dum_2,((2*mband)**formeig*mband))
             #  #  #  # ]
     676   [ #  #  #  # ]:           0 :    dudk(1:2,:)=0.0_dp
     677         [ #  # ]:           0 :    eig_dum_2=0.0_dp
     678         [ #  # ]:           0 :    occ_dum_2=0.0_dp
     679                 :             : 
     680         [ #  # ]:           0 :    if (mkmem/=0) then
     681                 :             : 
     682                 :             : !    Find the location of each wavefunction
     683                 :             : 
     684   [ #  #  #  #  :           0 :      ABI_MALLOC(cg_index,(mband,nkpt_,nsppol))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     685                 :           0 :      icg = 0
     686         [ #  # ]:           0 :      do isppol=1,nsppol
     687         [ #  # ]:           0 :        do ikpt=1,nkpt_
     688                 :           0 :          nband_k=nband(ikpt+(isppol-1)*nkpt_)
     689                 :           0 :          npw_k=npwarr(ikpt)
     690         [ #  # ]:           0 :          do iband=1,nband_k
     691                 :           0 :            cg_index(iband,ikpt,isppol)=(iband-1)*npw_k*nspinor+icg
     692                 :             :          end do
     693                 :           0 :          icg=icg+npw_k*nspinor*nband(ikpt)
     694                 :             :        end do
     695                 :             :      end do
     696                 :             : 
     697                 :             : !    Find the planewave vectors for each k point
     698                 :             : !    SHOULD BE REMOVED WHEN ANOTHER INDEXING TECHNIQUE WILL BE USED FOR kg
     699   [ #  #  #  #  :           0 :      ABI_MALLOC(kg_kpt,(3,mpw*nspinor,nkpt_))
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     700   [ #  #  #  #  :           0 :      kg_kpt(:,:,:) = 0
                   #  # ]
     701                 :           0 :      index1 = 0
     702         [ #  # ]:           0 :      do ikpt=1,nkpt_
     703                 :           0 :        npw_k=npwarr(ikpt)
     704         [ #  # ]:           0 :        do ipw=1,npw_k*nspinor
     705         [ #  # ]:           0 :          kg_kpt(1:3,ipw,ikpt)=kg(1:3,ipw+index1)
     706                 :             :        end do
     707                 :           0 :        index1=index1+npw_k*nspinor
     708                 :             :      end do
     709                 :             :    end if
     710                 :             : 
     711                 :             : !  *************************************************************************
     712                 :             : !  Loop over spins
     713         [ #  # ]:           0 :    do isppol=1,nsppol
     714                 :             : 
     715                 :           0 :      minband=bdberry(2*isppol-1)
     716                 :           0 :      maxband=bdberry(2*isppol)
     717                 :             : 
     718         [ #  # ]:           0 :      if(minband<1)then
     719                 :           0 :        write(message,'(a,i0,a)')'  The band limit minband= ',minband,', is lower than 0.'
     720                 :           0 :        ABI_BUG(message)
     721                 :             :      end if
     722                 :             : 
     723         [ #  # ]:           0 :      if(maxband<1)then
     724                 :           0 :        write(message,'(a,i0,a)')' The band limit maxband= ',maxband,', is lower than 0.'
     725                 :           0 :        ABI_BUG(message)
     726                 :             :      end if
     727                 :             : 
     728         [ #  # ]:           0 :      if(maxband<minband)then
     729                 :           0 :        write(message,'(a,i0,a,i0)')' maxband= ',maxband,', is lower than minband= ',minband
     730                 :           0 :        ABI_BUG(message)
     731                 :             :      end if
     732                 :             : 
     733                 :             : !    Loop over k points
     734         [ #  # ]:           0 :      do ikpt_=1,nkpt_
     735                 :             : 
     736                 :           0 :        read_k = 0
     737                 :             : 
     738                 :           0 :        ikpt=ikpt_
     739                 :           0 :        tr(1) = 1.0_dp
     740                 :             : 
     741         [ #  # ]:           0 :        if (kptopt==2) then
     742                 :             :          if (read_k == 0) then
     743         [ #  # ]:           0 :            if (kpt_flag(ikpt_)/=0) then
     744                 :           0 :              tr(1) = -1.0_dp
     745                 :           0 :              ikpt= kpt_flag(ikpt_)
     746                 :             :            end if
     747                 :             :          else           !read_k
     748                 :             :            if (kpt_flag(ikpt_)/=0) then
     749                 :             :              tr(-1*read_k+3) = -1.0_dp
     750                 :             :              ikpt= kpt_flag(ikpt_)
     751                 :             :            end if
     752                 :             :          end if       !read_k
     753                 :             :        end if           !kptopt
     754                 :             : 
     755                 :           0 :        nband_k=nband(ikpt+(isppol-1)*nkpt_)
     756                 :             : 
     757         [ #  # ]:           0 :        if(nband_k<maxband)then
     758                 :           0 :          write(message,'(a,i0,a,i0)')'  maxband=',maxband,', is larger than nband(i,isppol)=',nband_k
     759                 :           0 :          ABI_BUG(message)
     760                 :             :        end if
     761                 :             : 
     762                 :           0 :        npw_k=npwarr(ikpt)
     763                 :             : 
     764   [ #  #  #  #  :           0 :        ABI_MALLOC(u_tilde,(2,npw_k,maxband,2))
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     765   [ #  #  #  #  :           0 :        u_tilde(1:2,1:npw_k,1:maxband,1:2)=0.0_dp
             #  #  #  # ]
     766                 :             : 
     767                 :             : !      ifor = 1,2 represents forward and backward neighbouring k points of ikpt
     768                 :             : !      respectively along dk direction
     769                 :             : 
     770         [ #  # ]:           0 :        do ifor=1,2
     771                 :             : 
     772   [ #  #  #  #  :           0 :          ABI_MALLOC(phi,(2,mpw,mband))
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     773   [ #  #  #  #  :           0 :          ABI_MALLOC(cmatrix,(2,maxband,maxband))
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     774   [ #  #  #  #  :           0 :          phi(1:2,1:mpw,1:mband)=0.0_dp; cmatrix(1:2,1:maxband,1:maxband)=0.0_dp
          #  #  #  #  #  
                #  #  # ]
     775                 :             : 
     776                 :           0 :          isgn=(-1)**ifor
     777                 :           0 :          jkpt_= ikpt_dk(ifor,ikpt_)
     778                 :             : 
     779                 :           0 :          tr(2) = 1.0_dp
     780                 :             : 
     781                 :           0 :          jkpt=jkpt_
     782                 :             : 
     783         [ #  # ]:           0 :          if (kptopt==2) then
     784         [ #  # ]:           0 :            if (read_k == 0) then
     785         [ #  # ]:           0 :              if (kpt_flag(jkpt_)/=0) then
     786                 :           0 :                tr(2) = -1.0_dp
     787                 :           0 :                jkpt= kpt_flag(jkpt_)
     788                 :             :              end if
     789                 :             :            else           !read_k
     790         [ #  # ]:           0 :              if (kpt_flag(jkpt_)/=0) then
     791                 :           0 :                tr(read_k) = -1.0_dp
     792                 :           0 :                jkpt= kpt_flag(jkpt_)
     793                 :             :              end if
     794                 :             :            end if       !read_k
     795                 :             :          end if           !kptopt
     796                 :             : 
     797         [ #  # ]:           0 :          if (ifor==1) read_k = 2
     798                 :             : 
     799                 :           0 :          jj = read_k
     800                 :           0 :          ii = -1*read_k+3
     801                 :             : 
     802                 :             :          call waveformat(cg,cg_disk,cg_index,phi,dk,ii,ikpt,&
     803                 :             : &         ikpt_,isgn,isppol,jj,jkpt,jkpt_,kg_kpt,kpt,kg_jl,maxband,mband,mcg,mcg_disk,&
     804                 :           0 : &         minband,mkmem,mpw,nkpt,nkpt_,npwarr,nsppol,nspinor,shift_g_2,tr)
     805                 :             : 
     806                 :             : !        Compute the overlap matrix <u_k|u_k+b>
     807                 :             : 
     808         [ #  # ]:           0 :          do iband=minband,maxband
     809                 :           0 :            cg_index_iband=cg_index(iband,ikpt,isppol)
     810         [ #  # ]:           0 :            do jband=minband,maxband
     811         [ #  # ]:           0 :              do ipw=1,npwarr(ikpt)
     812                 :             :                cmatrix(1,iband,jband)=cmatrix(1,iband,jband)+&
     813                 :             : &               cg(1,ipw+cg_index_iband)*phi(1,ipw,jband)+&
     814                 :           0 : &               tr(ii)*cg(2,ipw+cg_index_iband)*tr(jj)*phi(2,ipw,jband)
     815                 :             : 
     816                 :             :                cmatrix(2,iband,jband)=cmatrix(2,iband,jband)+&
     817                 :             : &               cg(1,ipw+cg_index_iband)*tr(jj)*phi(2,ipw,jband)-&
     818                 :           0 : &               tr(ii)*cg(2,ipw+cg_index_iband)*phi(1,ipw,jband)
     819                 :             :              end do
     820                 :             :            end do
     821                 :             :          end do
     822                 :             : 
     823                 :             : !        Compute the inverse of cmatrix(1:2,minband:maxband, minband:maxband)
     824                 :             : 
     825                 :           0 :          band_in = maxband - minband + 1
     826   [ #  #  #  #  :           0 :          ABI_MALLOC(ipvt,(maxband))
          #  #  #  #  #  
                #  #  # ]
     827   [ #  #  #  #  :           0 :          ABI_MALLOC(zgwork,(2,1:maxband))
          #  #  #  #  #  
                #  #  # ]
     828                 :             : 
     829                 :             : !        Last argument of zgedi means calculate inverse only
     830                 :           0 :          call dzgefa(cmatrix(1,minband,minband),maxband, band_in,ipvt,info)
     831                 :           0 :          call dzgedi(cmatrix(1,minband,minband),maxband, band_in,ipvt,det,zgwork,01)
     832                 :             : 
     833         [ #  # ]:           0 :          ABI_FREE(zgwork)
     834         [ #  # ]:           0 :          ABI_FREE(ipvt)
     835                 :             : 
     836                 :             : !        Compute the product of Inverse overlap matrix with the wavefunction
     837                 :             : 
     838         [ #  # ]:           0 :          do iband=minband,maxband
     839         [ #  # ]:           0 :            do ipw=1,npwarr(ikpt)
     840                 :             :              u_tilde(1,ipw,iband,ifor)= &
     841                 :             : &             dot_product(cmatrix(1,minband:maxband,iband),&
     842                 :             : &             phi(1,ipw,minband:maxband))-&
     843                 :             : &             dot_product(cmatrix(2,minband:maxband,iband),&
     844   [ #  #  #  # ]:           0 : &             tr(jj)*phi(2,ipw,minband:maxband))
     845                 :             :              u_tilde(2,ipw,iband,ifor)= &
     846                 :             : &             dot_product(cmatrix(1,minband:maxband,iband),&
     847                 :             : &             tr(jj)*phi(2,ipw,minband:maxband))+&
     848                 :             : &             dot_product(cmatrix(2,minband:maxband,iband),&
     849   [ #  #  #  # ]:           0 : &             phi(1,ipw,minband:maxband))
     850                 :             :            end do
     851                 :             :          end do
     852         [ #  # ]:           0 :          ABI_FREE(cmatrix)
     853         [ #  # ]:           0 :          ABI_FREE(phi)
     854                 :             : 
     855                 :             :        end do !ifor
     856                 :             : 
     857                 :             : !      Compute dudk for ikpt
     858                 :             : 
     859                 :             :        npw_k=npwarr(ikpt)
     860                 :             : 
     861         [ #  # ]:           0 :        do iband=minband,maxband
     862                 :             : 
     863                 :           0 :          icg=(iband-minband)*npw_k
     864                 :             : 
     865                 :             :          dudk(1,1+icg:npw_k+icg)=(u_tilde(1,1:npw_k,iband,1)-&
     866         [ #  # ]:           0 : &         u_tilde(1,1:npw_k,iband,2))/twodk
     867                 :             : 
     868                 :             :          dudk(2,1+icg:npw_k+icg)=(u_tilde(2,1:npw_k,iband,1)-&
     869         [ #  # ]:           0 : &         u_tilde(2,1:npw_k,iband,2))/twodk
     870                 :             : 
     871                 :             :        end do
     872                 :             : 
     873                 :           0 :        tim_rwwf=0
     874                 :           0 :        mcg_disk=mpw*nspinor*mband
     875                 :           0 :        nband_diff=maxband-minband+1
     876                 :             :        call rwwf(dudk,eig_dum_2,formeig,0,0,ikpt,isppol,kg_kpt(:,:,ikpt),&
     877                 :             : &       mband,mcg_disk,mpi_enreg,nband_diff,nband_diff,&
     878                 :           0 : &       npw_k,nspinor,occ_dum_2,2,1,tim_rwwf,wffddk)
     879                 :             : 
     880                 :             :        !call wfk_read_band_block(wfk, band_block, ikpt, isppol, sc_mode,
     881                 :             :        !  kg_k=kg_kpt(:,:,ikpt), cg_k=dudk, eig_k=eig_dum, occ_k=occ_dum)
     882                 :             : 
     883         [ #  # ]:           0 :        ABI_FREE(u_tilde)
     884                 :             : 
     885                 :             :      end do !ikpt
     886                 :             :    end do  !isppol
     887                 :             : 
     888         [ #  # ]:           0 :    ABI_FREE(eig_dum_2)
     889         [ #  # ]:           0 :    ABI_FREE(occ_dum_2)
     890         [ #  # ]:           0 :    ABI_FREE(dudk)
     891                 :             : 
     892                 :           0 :    call WffClose(wffddk,ierr)
     893                 :             :    !call wfk_close(wfk)
     894                 :             : 
     895         [ #  # ]:           0 :    ABI_FREE(kg_kpt)
     896         [ #  # ]:           0 :    ABI_FREE(cg_index)
     897         [ #  # ]:           0 :    ABI_FREE(ikpt_dk)
     898                 :             : 
     899                 :             :  end do ! iberry
     900                 :             : 
     901         [ #  # ]:           0 :  ABI_FREE(shift_g_2)
     902         [ #  # ]:           0 :  ABI_FREE(kpt)
     903                 :             : 
     904                 :           0 :  write(std_out,*) 'uderiv:  exit '
     905                 :             : 
     906                 :           0 : end subroutine uderiv
     907                 :             : !!***
     908                 :             : 
     909                 :             : 
     910                 :             : !!****f* ABINIT/waveformat
     911                 :             : !! NAME
     912                 :             : !! waveformat
     913                 :             : !!
     914                 :             : !! FUNCTION
     915                 :             : !! This routine is to find the matched pairs of plane waves between
     916                 :             : !! two neighbouring k points and load a new pw coefficients array cg_new
     917                 :             : !! Was written first by Na Sai (thanks), but unfortunately without
     918                 :             : !! any comment ...
     919                 :             : !!
     920                 :             : !! INPUTS
     921                 :             : !!  cg(2,mpw*nspinor*mband*mkmem*nsppol)= input planewave coefficients, in case mkmem/=0
     922                 :             : !!  cg_disk(2,mpw*nspinor*mband,2)= input planewave coefficients, in case mkmem==0
     923                 :             : !!  cg_index(mband,nkpt_,nsppol)=index of wavefunction iband,ikpt,isppol in the array cg.
     924                 :             : !!  dk(3)= step taken to the next k mesh point along the kberry direction (see also isgn)
     925                 :             : !!  ii=(to be documented)
     926                 :             : !!  ikpt=index of the first k-point in the reduced Brillouin zone
     927                 :             : !!  ikpt_=index of the first k-point in the full Brillouin zone
     928                 :             : !!  isgn=1 if dk(3) is connecting the k-points (ikpt_ and jkpt)
     929                 :             : !!      =-1 if -dk(3) is connecting the k-points
     930                 :             : !!  isppol=1 if spin-up, =2 if spin-down
     931                 :             : !!  jj=(to be documented)
     932                 :             : !!  jkpt=index of the second k-point in the reduced Brillouin zone
     933                 :             : !!  jkpt_=index of the second k-point in the full Brillouin zone
     934                 :             : !!  kg_kpt(:,:,:)= unpacked reduced planewave coordinates with subscript of
     935                 :             : !!          planewave and k point
     936                 :             : !!  kpt(3,nkpt)=reduced coordinates of k-point grid that samples the whole BZ
     937                 :             : !!  kg_jl(3,mpw,2)=(to be documented)
     938                 :             : !!  maxband/minband= control the minimum and maximum band calculated in the
     939                 :             : !!           overlap matrix
     940                 :             : !!  mband=maximum number of bands (dimension of several cg* arrays)
     941                 :             : !!  mcg=size of wave-functions array (cg) =mpw*nspinor*mband*mkmem*nsppol
     942                 :             : !!  mcg_disk=size of wave-functions array (cg_disk) =mpw*nspinor*mband
     943                 :             : !!  mkmem= if 0, the wavefunctions are input in cg_disk, otherwise in cg
     944                 :             : !!  mpw=maximum number of planewaves (dimension of several cg* arrays)
     945                 :             : !!  nkpt=number of k points (full Brillouin zone !?!)
     946                 :             : !!  nkpt_=number of k points (reduced Brillouin zone !?!)
     947                 :             : !!  npwarr(nkpt)=number of planewaves in basis at this k point
     948                 :             : !!  nspinor=number of spinorial components of the wavefunctions
     949                 :             : !!  nsppol=1 for unpolarized, 2 for spin-polarized
     950                 :             : !!  shift_g_2(nkpt,nkpt)=non-zero if a G vector along kberry is needed to connect k points
     951                 :             : !!  tr(2)=variable that changes k to -k
     952                 :             : !!                              G to -G
     953                 :             : !!                     $c_g$ to $c_g^*$ when time-reversal symetrie is used
     954                 :             : !!
     955                 :             : !! OUTPUT
     956                 :             : !!  cg_new(2,mpw,maxband)=planewave coefficients transferred onto the
     957                 :             : !!   set of planewaves at k
     958                 :             : !!
     959                 :             : !! SIDE EFFECTS
     960                 :             : !!
     961                 :             : !! SOURCE
     962                 :             : 
     963                 :           0 : subroutine waveformat(cg,cg_disk,cg_index,cg_new,dk,ii,ikpt,&
     964                 :           0 : & ikpt_,isgn,isppol,jj,jkpt,jkpt_,kg_kpt,kpt,kg_jl,maxband,mband,mcg,mcg_disk,&
     965                 :           0 : & minband,mkmem,mpw,nkpt,nkpt_,npwarr,nsppol,nspinor,shift_g_2,tr)
     966                 :             : 
     967                 :             : !Arguments ------------------------------------
     968                 :             : !scalars
     969                 :             :  integer,intent(in) :: ii,ikpt,ikpt_,isgn,isppol,jj,jkpt,jkpt_,maxband,mband,mcg,mcg_disk
     970                 :             :  integer,intent(in) :: minband,mkmem,mpw,nkpt,nkpt_,nspinor,nsppol
     971                 :             : !arrays
     972                 :             :  integer,intent(in) :: cg_index(mband,nkpt_,nsppol),kg_jl(3,mpw,2)
     973                 :             :  integer,intent(in) :: kg_kpt(3,mpw*nspinor,nkpt_),npwarr(nkpt_)
     974                 :             :  real(dp),intent(in) :: cg(2,mcg)
     975                 :             :  real(dp),intent(in) :: cg_disk(2,mcg_disk,2),dk(3),kpt(3,nkpt),tr(2)
     976                 :             :  real(dp),intent(out) :: cg_new(2,mpw,maxband)
     977                 :             :  logical,intent(in) :: shift_g_2(nkpt,nkpt)
     978                 :             : 
     979                 :             : !Local variables -------------------------
     980                 :             : !scalars
     981                 :             :  integer :: cg_index_iband,iband,ipw,jpw,nomatch,npw_k
     982                 :             :  logical :: found_match
     983                 :             : !arrays
     984                 :             :  integer :: dg(3)
     985                 :             : 
     986                 :             : ! ***********************************************************************
     987                 :             : 
     988                 :           0 :  npw_k=npwarr(ikpt)
     989                 :             : 
     990                 :             : 
     991                 :           0 :  nomatch=0
     992                 :             : 
     993                 :             : !If there is no shift of G-vector between ikpt_ and jkpt_
     994         [ #  # ]:           0 :  if(shift_g_2(ikpt_,jkpt_) .eqv. .false.) then
     995                 :             : 
     996                 :             : !  DEBUG
     997                 :             : !  write(111,*)'pair', ikpt_,jkpt_,'noshift'
     998                 :             : !  ENDDEBUG
     999                 :             : 
    1000                 :             : !  If the original wavefunction is contained in cg_disk
    1001         [ #  # ]:           0 :    if(mkmem==0) then
    1002                 :             : 
    1003         [ #  # ]:           0 :      do ipw=1,npw_k
    1004                 :             : 
    1005                 :           0 :        found_match = .false.
    1006                 :             : 
    1007         [ #  # ]:           0 :        do jpw=1,npwarr(jkpt)
    1008   [ #  #  #  # ]:           0 :          if (sum(abs(tr(ii)*kg_jl(:,ipw,ii)-tr(jj)*kg_jl(:,jpw,jj)))<3*tol8)then
    1009         [ #  # ]:           0 :            do iband=minband, maxband
    1010                 :           0 :              cg_index_iband=(iband-1)*npwarr(jkpt)
    1011         [ #  # ]:           0 :              cg_new(1:2,ipw,iband)=cg_disk(1:2,jpw+cg_index_iband,jj)
    1012                 :             :            end do
    1013                 :             :            found_match = .true.
    1014                 :             :            exit
    1015                 :             :          end if
    1016                 :             :        end do
    1017                 :             : 
    1018         [ #  # ]:           0 :        if (found_match .eqv. .false.) then
    1019         [ #  # ]:           0 :          do iband=minband,maxband
    1020         [ #  # ]:           0 :            cg_new(1:2,ipw,iband)=zero
    1021                 :             :          end do
    1022                 :           0 :          nomatch = nomatch + 1
    1023                 :             :        end if
    1024                 :             : 
    1025                 :             :      end do
    1026                 :             : 
    1027                 :             : !    Here, the wavefunctions are contained in cg
    1028                 :             :    else
    1029                 :             : 
    1030         [ #  # ]:           0 :      do ipw=1,npw_k
    1031                 :             : 
    1032                 :           0 :        found_match = .false.
    1033                 :             : 
    1034         [ #  # ]:           0 :        do jpw=1,npwarr(jkpt)
    1035   [ #  #  #  # ]:           0 :          if (sum(abs(tr(ii)*kg_kpt(:,ipw,ikpt)-tr(jj)*kg_kpt(:,jpw,jkpt)))<3*tol8)then
    1036         [ #  # ]:           0 :            do iband=minband, maxband
    1037                 :           0 :              cg_index_iband=cg_index(iband,jkpt,isppol)
    1038         [ #  # ]:           0 :              cg_new(1:2,ipw,iband)=cg(1:2,jpw+cg_index_iband)
    1039                 :             :            end do
    1040                 :             :            found_match = .true.
    1041                 :             :            exit
    1042                 :             :          end if
    1043                 :             :        end do
    1044                 :             : 
    1045         [ #  # ]:           0 :        if (found_match .eqv. .false.) then
    1046         [ #  # ]:           0 :          do iband=minband,maxband
    1047         [ #  # ]:           0 :            cg_new(1:2,ipw,iband)=(0.0_dp,0.0_dp)
    1048                 :             :          end do
    1049                 :           0 :          nomatch = nomatch + 1
    1050                 :             :        end if
    1051                 :             :      end do
    1052                 :             : 
    1053                 :             :    end if
    1054                 :             : 
    1055                 :             : !  DEBUG
    1056                 :             : !  write(111,*) 'normal pair nomatch=',nomatch
    1057                 :             : !  ENDDEBUG
    1058                 :             : 
    1059                 :             : !  If there is a G-vector shift between ikpt_ and jkpt_
    1060                 :             :  else
    1061                 :             : 
    1062                 :             : !  DEBUG
    1063                 :             : !  write(111,*) 'pair',ikpt_,jkpt_,' need shift'
    1064                 :             : !  ENDDEBUG
    1065                 :             : 
    1066         [ #  # ]:           0 :    dg(:) = -1*nint(tr(jj)*kpt(:,jkpt)-tr(ii)*kpt(:,ikpt)+isgn*dk(:))
    1067                 :             : 
    1068                 :             : !  If the original wavefunction is contained in cg_disk
    1069         [ #  # ]:           0 :    if(mkmem==0) then
    1070                 :             : 
    1071         [ #  # ]:           0 :      do ipw=1,npw_k
    1072                 :             : 
    1073                 :           0 :        found_match = .false.
    1074                 :             : 
    1075         [ #  # ]:           0 :        do jpw=1,npwarr(jkpt)
    1076   [ #  #  #  # ]:           0 :          if (sum(abs(tr(ii)*kg_jl(:,ipw,ii)-(tr(jj)*kg_jl(:,jpw,jj)-&
    1077                 :           0 : &         dg(:))))<3*tol8)then
    1078                 :             : 
    1079         [ #  # ]:           0 :            do iband=minband, maxband
    1080                 :           0 :              cg_index_iband=(iband-1)*npwarr(jkpt)
    1081         [ #  # ]:           0 :              cg_new(1:2,ipw,iband)=cg_disk(1:2,jpw+cg_index_iband,jj)
    1082                 :             :            end do
    1083                 :             :            found_match = .true.
    1084                 :             :            exit
    1085                 :             :          end if
    1086                 :             :        end do
    1087                 :             : 
    1088         [ #  # ]:           0 :        if (found_match .eqv. .false.) then
    1089         [ #  # ]:           0 :          do iband=minband,maxband
    1090         [ #  # ]:           0 :            cg_new(1:2,ipw,iband)=(0.0_dp,0.0_dp)
    1091                 :             :          end do
    1092                 :           0 :          nomatch = nomatch + 1
    1093                 :             :        end if
    1094                 :             :      end do
    1095                 :             : 
    1096                 :             : !    Here, the wavefunctions are contained in cg
    1097                 :             :    else
    1098                 :             : 
    1099         [ #  # ]:           0 :      do ipw=1,npw_k
    1100                 :             : 
    1101                 :           0 :        found_match = .false.
    1102                 :             : 
    1103         [ #  # ]:           0 :        do jpw=1,npwarr(jkpt)
    1104   [ #  #  #  # ]:           0 :          if (sum(abs(tr(ii)*kg_kpt(:,ipw,ikpt)-(tr(jj)*kg_kpt(:,jpw,jkpt)-&
    1105                 :           0 : &         dg(:))))<3*tol8)then
    1106         [ #  # ]:           0 :            do iband=minband, maxband
    1107                 :           0 :              cg_index_iband=cg_index(iband,jkpt,isppol)
    1108         [ #  # ]:           0 :              cg_new(1:2,ipw,iband)=cg(1:2,jpw+cg_index_iband)
    1109                 :             :            end do
    1110                 :             :            found_match = .true.
    1111                 :             :            exit
    1112                 :             :          end if
    1113                 :             :        end do
    1114                 :             : 
    1115         [ #  # ]:           0 :        if (found_match .eqv. .false.) then
    1116         [ #  # ]:           0 :          do iband=minband,maxband
    1117         [ #  # ]:           0 :            cg_new(1:2,ipw,iband)=zero
    1118                 :             :          end do
    1119                 :           0 :          nomatch = nomatch + 1
    1120                 :             :        end if
    1121                 :             :      end do
    1122                 :             : 
    1123                 :             :    end if
    1124                 :             : 
    1125                 :             : !  DEBUG
    1126                 :             : !  write(111,*) 'special pair nomatch=',nomatch
    1127                 :             : !  ENDDEBUG
    1128                 :             : 
    1129                 :             :  end if
    1130                 :             : 
    1131                 :           0 : end subroutine waveformat
    1132                 :             : !!***
    1133                 :             : 
    1134                 :             : end module m_elpolariz
    1135                 :             : !!***
        

Generated by: LCOV version 2.3-1