2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! Copyright (C) 2001 PWSCF group
|
|
|
|
! This file is distributed under the terms of the
|
|
|
|
! GNU General Public License. See the file `License'
|
|
|
|
! in the root directory of the present distribution,
|
|
|
|
! or http://www.gnu.org/copyleft/gpl.txt .
|
|
|
|
!
|
|
|
|
|
|
|
|
!-----------------------------------------------------------------------
|
2003-02-08 00:04:36 +08:00
|
|
|
subroutine phq_setup
|
2003-01-20 05:58:50 +08:00
|
|
|
!-----------------------------------------------------------------------
|
|
|
|
!
|
|
|
|
! This subroutine prepares several variables which are needed in the
|
|
|
|
! phonon program:
|
|
|
|
! 1) put the correct units on the masses
|
|
|
|
! 2) computes the total local potential (external+scf) on the smoot
|
|
|
|
! grid to be used in h_psi and similia
|
|
|
|
! 3) computes dmuxc 3.1) with GC if needed
|
|
|
|
! 4) set the inverse of every matrix invs
|
|
|
|
! 5) for metals sets the occupated bands
|
|
|
|
! 6) computes alpha_pv
|
|
|
|
! 7) computes the variables needed to pass to the pattern representatio
|
|
|
|
! u the patterns
|
|
|
|
! t the matrices of the small group of q on the pattern basis
|
|
|
|
! tmq the matrix of the symmetry which sends q -> -q + G
|
|
|
|
! gi the G associated to each symmetry operation
|
|
|
|
! gimq the G of the q -> -q+G symmetry
|
|
|
|
! irgq the small group indices
|
|
|
|
! nsymq the order of the small group of q
|
|
|
|
! irotmq the index of the q->-q+G symmetry
|
|
|
|
! nirr the number of irreducible representation
|
|
|
|
! npert the dimension of each irreducible representation
|
|
|
|
! nmodes the number of modes
|
|
|
|
! minus_q true if there is a symmetry sending q -> -q+G
|
|
|
|
! 8) for testing purpouses it sets ubar
|
|
|
|
! 9) set the variables needed to deal with nlcc
|
|
|
|
! 10) set the variables needed for the partial computation
|
|
|
|
! of the dynamical matrix
|
|
|
|
!
|
|
|
|
! Revised 1 Oct. 1995 by Andrea Dal Corso
|
|
|
|
! March 1997: nlcc stuff added (SdG)
|
|
|
|
! April 1997: parallel stuff added (SdG)
|
|
|
|
! Oct-Nov 1998: minor stuff added (SdG)
|
|
|
|
!
|
|
|
|
#include "machine.h"
|
2003-11-06 03:01:20 +08:00
|
|
|
USE io_global, ONLY : stdout
|
2003-02-08 00:04:36 +08:00
|
|
|
use pwcom
|
2003-10-03 22:01:11 +08:00
|
|
|
USE constants, ONLY: degspin
|
2003-02-08 00:04:36 +08:00
|
|
|
use parameters, only : DP
|
2003-01-20 05:58:50 +08:00
|
|
|
use phcom
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
real(kind=DP) :: rhotot, rhoup, rhodw, target, small, fac, xmax, emin, &
|
|
|
|
emax, dmxc
|
|
|
|
! total charge
|
|
|
|
! total up charge
|
|
|
|
! total down charge
|
|
|
|
! auxiliary variables used
|
|
|
|
! to set nbnd_occ in the metallic case
|
|
|
|
! minimum band energy
|
|
|
|
! maximum band energy
|
|
|
|
! computes derivative of xc potential
|
|
|
|
|
|
|
|
integer :: ir, table (48, 48), isym, jsym, irot, ik, ibnd, ipol, &
|
|
|
|
mu, nu, imode0, irr, ipert, na, it, nt
|
|
|
|
! counter on mesh points
|
|
|
|
! the multiplication table of the point g
|
|
|
|
! counter on symmetries
|
|
|
|
! counter on symmetries
|
|
|
|
! counter on rotations
|
|
|
|
! counter on k points
|
|
|
|
! counter on bands
|
|
|
|
! counter on polarizations
|
|
|
|
! counter on modes
|
|
|
|
! the starting mode
|
|
|
|
! counter on representation and perturbat
|
|
|
|
! counter on atoms
|
|
|
|
! counter on iterations
|
|
|
|
! counter on atomic type
|
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
logical :: sym (48)
|
2003-01-20 05:58:50 +08:00
|
|
|
! the symmetry operations
|
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
call start_clock ('phq_setup')
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! 1) We start with the mass renormalization
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
call DSCAL (ntyp, amconv, amass, 1)
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
2003-10-15 19:40:07 +08:00
|
|
|
! 2) Computes the total local potential (external+scf) on the smooth grid
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
call set_vrs (vrs, vltot, vr, nrxx, nspin, doublegrid)
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! 2.a) Set non linear core correction stuff
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
nlcc_any = .false.
|
|
|
|
do nt = 1, ntyp
|
|
|
|
nlcc_any = nlcc_any.or.nlcc (nt)
|
2003-01-20 05:58:50 +08:00
|
|
|
|
|
|
|
enddo
|
2003-02-08 00:04:36 +08:00
|
|
|
if (nlcc_any) allocate (drc( ngm, ntyp))
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! 3) Computes the derivative of the xc potential
|
|
|
|
!
|
2003-10-15 19:40:07 +08:00
|
|
|
dmuxc(:,:,:) = 0.d0
|
2003-02-08 00:04:36 +08:00
|
|
|
if (lsda) then
|
|
|
|
do ir = 1, nrxx
|
|
|
|
rhoup = rho (ir, 1) + 0.5d0 * rho_core (ir)
|
|
|
|
rhodw = rho (ir, 2) + 0.5d0 * rho_core (ir)
|
2003-04-23 00:03:45 +08:00
|
|
|
call dmxc_spin (rhoup, rhodw, dmuxc(ir,1,1), dmuxc(ir,2,1), &
|
|
|
|
dmuxc(ir,1,2), dmuxc(ir,2,2) )
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
2003-02-08 00:04:36 +08:00
|
|
|
else
|
|
|
|
do ir = 1, nrxx
|
|
|
|
rhotot = rho (ir, nspin) + rho_core (ir)
|
|
|
|
if (rhotot.gt.1.d-30) dmuxc (ir, 1, 1) = dmxc (rhotot)
|
|
|
|
if (rhotot.lt. - 1.d-30) dmuxc (ir, 1, 1) = - dmxc ( - rhotot)
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
endif
|
|
|
|
!
|
|
|
|
! 3.1) Setup all gradient correction stuff
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
call setup_dgc
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! 4) Computes the inverse of each matrix
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
call multable (nsym, s, table)
|
|
|
|
do isym = 1, nsym
|
|
|
|
do jsym = 1, nsym
|
|
|
|
if (table (isym, jsym) .eq.1) invs (isym) = jsym
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
enddo
|
|
|
|
!
|
|
|
|
! 5) Computes the number of occupated bands for each k point
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
if (degauss.ne.0.d0) then
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! discard conduction bands such that w0gauss(x,n) < small
|
|
|
|
!
|
|
|
|
! hint:
|
|
|
|
! small = 1.0333492677046d-2 ! corresponds to 2 gaussian sigma
|
|
|
|
! small = 6.9626525973374d-5 ! corresponds to 3 gaussian sigma
|
|
|
|
! small = 6.3491173359333d-8 ! corresponds to 4 gaussian sigma
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
small = 6.9626525973374d-5
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! - limit appropriated for gaussian broadening (used for all ngauss)
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
xmax = sqrt ( - log (sqrt (pi) * small) )
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! - limit appropriated for Fermi-Dirac
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
if (ngauss.eq. - 99) then
|
|
|
|
fac = 1.d0 / sqrt (small)
|
|
|
|
xmax = 2.d0 * log (0.5d0 * (fac + sqrt (fac * fac - 4.d0) ) )
|
2003-01-20 05:58:50 +08:00
|
|
|
|
|
|
|
endif
|
2003-02-08 00:04:36 +08:00
|
|
|
target = ef + xmax * degauss
|
|
|
|
do ik = 1, nks
|
|
|
|
do ibnd = 1, nbnd
|
|
|
|
if (et (ibnd, ik) .lt.target) nbnd_occ (ik) = ibnd
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
2003-11-06 03:01:20 +08:00
|
|
|
if (nbnd_occ (ik) .eq.nbnd) WRITE( stdout, '(5x,/,&
|
2003-04-23 00:03:45 +08:00
|
|
|
&"Possibly too few bands at point ", i4,3f10.5)') &
|
|
|
|
ik, (xk (ipol, ik) , ipol = 1, 3)
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
2003-02-08 00:04:36 +08:00
|
|
|
else
|
2003-04-23 00:03:45 +08:00
|
|
|
if (lsda) call errore('phq_setup','occupation numbers probably wrong', -1)
|
2003-02-08 00:04:36 +08:00
|
|
|
do ik = 1, nks
|
|
|
|
nbnd_occ (ik) = nint (nelec) / degspin
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
endif
|
|
|
|
!
|
|
|
|
! 6) Computes alpha_pv
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
emin = et (1, 1)
|
|
|
|
do ik = 1, nks
|
|
|
|
do ibnd = 1, nbnd
|
|
|
|
emin = min (emin, et (ibnd, ik) )
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
enddo
|
2003-02-21 22:57:00 +08:00
|
|
|
#ifdef __PARA
|
2003-01-20 05:58:50 +08:00
|
|
|
! find the minimum across pools
|
2003-04-23 00:03:45 +08:00
|
|
|
call poolextreme (emin, -1)
|
2003-01-20 05:58:50 +08:00
|
|
|
#endif
|
2003-02-08 00:04:36 +08:00
|
|
|
if (degauss.ne.0.d0) then
|
|
|
|
emax = target
|
|
|
|
alpha_pv = emax - emin
|
|
|
|
else
|
|
|
|
emax = et (1, 1)
|
|
|
|
do ik = 1, nks
|
|
|
|
do ibnd = 1, nbnd
|
|
|
|
emax = max (emax, et (ibnd, ik) )
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
enddo
|
2003-02-21 22:57:00 +08:00
|
|
|
#ifdef __PARA
|
2003-01-20 05:58:50 +08:00
|
|
|
! find the maximum across pools
|
2003-02-08 00:04:36 +08:00
|
|
|
call poolextreme (emax, + 1)
|
2003-01-20 05:58:50 +08:00
|
|
|
#endif
|
2003-02-08 00:04:36 +08:00
|
|
|
alpha_pv = 2.d0 * (emax - emin)
|
2003-01-20 05:58:50 +08:00
|
|
|
endif
|
|
|
|
! avoid zero value for alpha_pv
|
2003-02-08 00:04:36 +08:00
|
|
|
alpha_pv = max (alpha_pv, 1.0d-2)
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! 7) set all the variables needed to use the pattern representation
|
|
|
|
!
|
|
|
|
! allocate and calculate rtau, the rotated position of each atom
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
do isym = 1, nsym
|
|
|
|
sym (isym) = .true.
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
call sgam_ph (at, bg, nsym, s, irt, tau, rtau, nat, sym)
|
|
|
|
nmodes = 3 * nat
|
2003-01-20 05:58:50 +08:00
|
|
|
! if minus_q=.t. set_irr will search for
|
2003-02-08 00:04:36 +08:00
|
|
|
minus_q = (iswitch.gt. - 3)
|
2003-01-20 05:58:50 +08:00
|
|
|
! Sq=-q+G symmetry. On output minus_q=.t.
|
|
|
|
! if such a symmetry has been found
|
2003-02-08 00:04:36 +08:00
|
|
|
if (iswitch.eq. - 4) then
|
2003-01-20 05:58:50 +08:00
|
|
|
call set_irr_mode (nat, at, bg, xq, s, invs, nsym, rtau, irt, &
|
2003-04-23 00:03:45 +08:00
|
|
|
irgq, nsymq, minus_q, irotmq, t, tmq, max_irr_dim, u, npert, &
|
|
|
|
nirr, gi, gimq, iverbosity, modenum)
|
2003-02-08 00:04:36 +08:00
|
|
|
else
|
|
|
|
if (nsym.gt.1) then
|
2003-01-20 05:58:50 +08:00
|
|
|
call set_irr (nat, at, bg, xq, s, invs, nsym, rtau, irt, &
|
2003-04-23 00:03:45 +08:00
|
|
|
irgq, nsymq, minus_q, irotmq, t, tmq, max_irr_dim, u, npert, &
|
|
|
|
nirr, gi, gimq, iverbosity)
|
2003-02-08 00:04:36 +08:00
|
|
|
else
|
2003-04-23 00:03:45 +08:00
|
|
|
call set_irr_nosym (nat, at, bg, xq, s, invs, nsym, rtau, irt, &
|
|
|
|
irgq, nsymq, minus_q, irotmq, t, tmq, max_irr_dim, u, npert, &
|
|
|
|
nirr, gi, gimq, iverbosity)
|
2003-01-20 05:58:50 +08:00
|
|
|
endif
|
|
|
|
endif
|
|
|
|
|
|
|
|
if (fildrho.ne.' ') call io_pattern (fildrho,nirr,npert,u,+1)
|
|
|
|
|
|
|
|
!
|
|
|
|
! set maxirr if not already set
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
if (maxirr.le.0.or.maxirr.gt.nirr) maxirr = nirr + 1
|
|
|
|
if (niter_ph.lt.maxter) maxirr = 1
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! set the alpha_mix parameter
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
do it = 2, niter_ph
|
|
|
|
if (alpha_mix (it) .eq.0.d0) alpha_mix (it) = alpha_mix (it - 1)
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
!
|
|
|
|
! 8) Set the ubar
|
|
|
|
!
|
|
|
|
|
2003-10-15 19:40:07 +08:00
|
|
|
ubar(:) =( 0.d0,0.d0)
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! NB: the following instructions are for testing purposes of delta rho
|
|
|
|
! the user must know how many atoms there are in the system
|
|
|
|
!
|
|
|
|
! ubar(1)=(1.d-3,0.d0)
|
|
|
|
! ubar(5)=(1.d0,0.d0)
|
|
|
|
! ubar(6)=(1.d0,0.d0)
|
|
|
|
!
|
|
|
|
! 10) set the variables needed for the partial computation
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
if (nrapp.eq.0) then
|
|
|
|
if (nat_todo.eq.0) then
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! The partial computation option is not used, compute all atoms
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
do na = 1, nat
|
|
|
|
atomo (na) = na
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
2003-02-08 00:04:36 +08:00
|
|
|
nat_todo = nat
|
2003-01-20 05:58:50 +08:00
|
|
|
endif
|
|
|
|
!
|
|
|
|
! Sets the atoms which must be computed: the requested atoms and all
|
|
|
|
! the symmetry related atoms
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
do na = 1, nat
|
|
|
|
ifat (na) = 0
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
2003-02-08 00:04:36 +08:00
|
|
|
do na = 1, nat_todo
|
|
|
|
ifat (atomo (na) ) = 1
|
|
|
|
do isym = 1, nsymq
|
|
|
|
irot = irgq (isym)
|
|
|
|
ifat (irt (irot, atomo (na) ) ) = 1
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
enddo
|
|
|
|
!
|
|
|
|
! Computes again nat_todo, prepare the list atomo and sets all_comp
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
nat_todo = 0
|
|
|
|
do na = 1, nat
|
|
|
|
if (ifat (na) .eq.1) then
|
|
|
|
nat_todo = nat_todo + 1
|
|
|
|
atomo (nat_todo) = na
|
2003-01-20 05:58:50 +08:00
|
|
|
endif
|
|
|
|
enddo
|
|
|
|
!
|
|
|
|
! Find the irreducible representations to be computed
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
imode0 = 0
|
|
|
|
do irr = 1, nirr
|
|
|
|
comp_irr (irr) = 0
|
|
|
|
do ipert = 1, npert (irr)
|
|
|
|
mu = imode0 + ipert
|
|
|
|
do na = 1, nat
|
|
|
|
if (ifat (na) .eq.1.and.comp_irr (irr) .eq.0) then
|
|
|
|
do ipol = 1, 3
|
|
|
|
nu = 3 * (na - 1) + ipol
|
|
|
|
if (abs (u (nu, mu) ) .gt.1.d-6) comp_irr (irr) = 1
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
endif
|
|
|
|
enddo
|
|
|
|
enddo
|
2003-02-08 00:04:36 +08:00
|
|
|
imode0 = imode0 + npert (irr)
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
2003-02-08 00:04:36 +08:00
|
|
|
else
|
2003-02-21 22:57:00 +08:00
|
|
|
if (nrapp.gt.nirr) call errore ('phq_setup', 'too many representati &
|
2003-01-20 05:58:50 +08:00
|
|
|
&on', 1)
|
2003-02-08 00:04:36 +08:00
|
|
|
do irr = 1, nirr
|
|
|
|
comp_irr (irr) = 0
|
|
|
|
do mu = 1, nrapp
|
|
|
|
if (list (mu) .eq.irr) comp_irr (irr) = 1
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
enddo
|
2003-02-08 00:04:36 +08:00
|
|
|
do na = 1, nat
|
|
|
|
ifat (na) = 0
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
2003-02-08 00:04:36 +08:00
|
|
|
imode0 = 0
|
|
|
|
do irr = 1, nirr
|
|
|
|
if (comp_irr (irr) .eq.1) then
|
|
|
|
do ipert = 1, npert (irr)
|
|
|
|
do na = 1, nat
|
|
|
|
do ipol = 1, 3
|
|
|
|
mu = 3 * (na - 1) + ipol
|
2003-01-20 05:58:50 +08:00
|
|
|
if (abs (u (mu, imode0 + ipert) ) .gt.1.d-12) ifat (na) &
|
|
|
|
= 1
|
|
|
|
enddo
|
|
|
|
enddo
|
|
|
|
enddo
|
|
|
|
endif
|
2003-02-08 00:04:36 +08:00
|
|
|
imode0 = imode0 + npert (irr)
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
2003-02-08 00:04:36 +08:00
|
|
|
nat_todo = 0
|
|
|
|
do na = 1, nat
|
|
|
|
if (ifat (na) .eq.1) then
|
|
|
|
nat_todo = nat_todo + 1
|
|
|
|
atomo (nat_todo) = na
|
2003-01-20 05:58:50 +08:00
|
|
|
endif
|
|
|
|
enddo
|
|
|
|
endif
|
|
|
|
!
|
|
|
|
! Initialize done_irr, find max dimension of the irreps
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
all_comp = nat_todo.eq.nat
|
|
|
|
npertx = 0
|
|
|
|
do irr = 1, nirr
|
|
|
|
done_irr (irr) = 0
|
|
|
|
npertx = max (npertx, npert (irr) )
|
2003-01-20 05:58:50 +08:00
|
|
|
|
|
|
|
enddo
|
2003-02-08 00:04:36 +08:00
|
|
|
call stop_clock ('phq_setup')
|
|
|
|
return
|
2003-01-20 05:58:50 +08:00
|
|
|
end subroutine phq_setup
|