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-09-21 22:40:37 Functions: 33.3 % 3 1

            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