2003-01-20 05:58:50 +08:00
|
|
|
!
|
2005-02-25 22:51:41 +08:00
|
|
|
! Copyright (C) 2001-2005 PWSCF group
|
2003-01-20 05:58:50 +08:00
|
|
|
! 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 .
|
|
|
|
!
|
2004-06-26 01:25:37 +08:00
|
|
|
#include "f_defs.h"
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
2003-12-10 22:57:07 +08:00
|
|
|
!----------------------------------------------------------------------------
|
|
|
|
SUBROUTINE potinit()
|
|
|
|
!----------------------------------------------------------------------------
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
2004-03-24 17:36:50 +08:00
|
|
|
! ... This routine initializes the self consistent potential in the array
|
|
|
|
! ... vr. There are three possible cases:
|
|
|
|
!
|
2005-05-27 20:52:50 +08:00
|
|
|
! ... a) the code is restarting from a broken run:
|
|
|
|
! ... read rho from data stored during the previous run
|
|
|
|
! ... b) the code is performing a non-scf calculation following a scf one:
|
|
|
|
! ... read rho from the file produced by the scf calculation
|
|
|
|
! ... c) the code starts a new calculation:
|
|
|
|
! ... calculate rho as a sum of atomic charges
|
|
|
|
!
|
|
|
|
! ... In all cases the scf potential is recalculated and saved in vr
|
2004-03-24 17:36:50 +08:00
|
|
|
!
|
2005-02-25 22:51:41 +08:00
|
|
|
USE kinds, ONLY : DP
|
|
|
|
USE io_global, ONLY : stdout
|
|
|
|
USE cell_base, ONLY : alat, omega
|
|
|
|
USE ions_base, ONLY : nat, ityp, ntyp => nsp
|
|
|
|
USE basis, ONLY : startingpot
|
|
|
|
USE klist, ONLY : nelec
|
|
|
|
USE lsda_mod, ONLY : lsda, nspin
|
|
|
|
USE gvect, ONLY : ngm, gstart, nr1, nr2, nr3, nrx1, nrx2, nrx3, &
|
|
|
|
nrxx, nl, g, gg
|
|
|
|
USE gsmooth, ONLY : doublegrid
|
2005-05-25 01:17:27 +08:00
|
|
|
USE control_flags, ONLY : lscf
|
2005-02-25 22:51:41 +08:00
|
|
|
USE scf, ONLY : rho, rho_core, vltot, vr, vrs
|
|
|
|
USE ener, ONLY : ehart, etxc, vtxc
|
|
|
|
USE ldaU, ONLY : niter_with_fixed_ns
|
|
|
|
USE ldaU, ONLY : lda_plus_u, Hubbard_lmax, ns, nsnew
|
|
|
|
USE noncollin_module, ONLY : noncolin, factlist, pointlist, pointnum, &
|
|
|
|
mcons, i_cons, lambda, vtcon, report
|
|
|
|
USE io_files, ONLY : prefix, iunocc, input_drho
|
|
|
|
USE mp, ONLY : mp_bcast
|
|
|
|
USE mp_global, ONLY : intra_image_comm
|
|
|
|
USE io_global, ONLY : ionode, ionode_id
|
2003-12-10 22:57:07 +08:00
|
|
|
!
|
|
|
|
IMPLICIT NONE
|
|
|
|
!
|
|
|
|
! ... local variables
|
|
|
|
!
|
2005-02-25 22:51:41 +08:00
|
|
|
REAL (KIND=DP) :: charge ! the starting charge
|
|
|
|
REAL (KIND=DP) :: etotefield !
|
2003-12-10 22:57:07 +08:00
|
|
|
INTEGER :: ios
|
2005-02-25 22:51:41 +08:00
|
|
|
INTEGER :: ldim ! integer variable for I/O control
|
2003-12-10 22:57:07 +08:00
|
|
|
LOGICAL :: exst
|
|
|
|
!
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
2004-08-23 14:51:19 +08:00
|
|
|
IF ( ionode ) THEN
|
2004-03-24 17:36:50 +08:00
|
|
|
!
|
2005-05-27 20:52:50 +08:00
|
|
|
CALL seqopn( 4, TRIM( prefix )//'.rho', 'UNFORMATTED', exst )
|
2005-02-25 22:51:41 +08:00
|
|
|
!
|
2003-12-10 22:57:07 +08:00
|
|
|
IF ( exst ) THEN
|
2005-02-25 22:51:41 +08:00
|
|
|
!
|
2003-12-10 22:57:07 +08:00
|
|
|
CLOSE( UNIT = 4, STATUS = 'KEEP' )
|
2005-02-25 22:51:41 +08:00
|
|
|
!
|
2003-12-10 22:57:07 +08:00
|
|
|
ELSE
|
2005-02-25 22:51:41 +08:00
|
|
|
!
|
2003-12-10 22:57:07 +08:00
|
|
|
CLOSE( UNIT = 4, STATUS = 'DELETE' )
|
2005-02-25 22:51:41 +08:00
|
|
|
!
|
2003-12-10 22:57:07 +08:00
|
|
|
END IF
|
2004-03-24 17:36:50 +08:00
|
|
|
!
|
2003-12-10 22:57:07 +08:00
|
|
|
END IF
|
2004-03-24 17:36:50 +08:00
|
|
|
!
|
2004-08-23 14:51:19 +08:00
|
|
|
CALL mp_bcast( exst, ionode_id, intra_image_comm )
|
2003-12-10 22:57:07 +08:00
|
|
|
!
|
|
|
|
IF ( startingpot == 'file' .AND. exst ) THEN
|
2004-03-24 17:36:50 +08:00
|
|
|
!
|
2005-05-27 20:52:50 +08:00
|
|
|
! ... Cases a) and b): the charge density is read from file
|
2003-12-10 22:57:07 +08:00
|
|
|
!
|
2005-05-27 20:52:50 +08:00
|
|
|
CALL io_pot( -1, TRIM( prefix )//'.rho', rho, nspin )
|
|
|
|
!
|
2005-05-25 01:17:27 +08:00
|
|
|
IF ( lscf ) THEN
|
2005-05-27 20:52:50 +08:00
|
|
|
WRITE( stdout, '(/5X,"The initial density is read from file ", A20)' )&
|
|
|
|
TRIM( prefix ) // '.rho'
|
2003-12-10 22:57:07 +08:00
|
|
|
ELSE
|
2005-05-27 20:52:50 +08:00
|
|
|
WRITE( stdout, '(/5X,"The potential is recalculated from file ",A20)')&
|
|
|
|
TRIM( prefix ) // '.rho'
|
2003-12-10 22:57:07 +08:00
|
|
|
END IF
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
2003-12-10 22:57:07 +08:00
|
|
|
! ... The occupations ns also need to be read in order to build up
|
2004-12-21 23:28:01 +08:00
|
|
|
! ... the potential
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
2003-12-10 22:57:07 +08:00
|
|
|
IF ( lda_plus_u ) THEN
|
2004-03-24 17:36:50 +08:00
|
|
|
!
|
2003-02-10 16:58:33 +08:00
|
|
|
ldim = 2 * Hubbard_lmax + 1
|
2004-03-24 17:36:50 +08:00
|
|
|
!
|
2004-08-23 14:51:19 +08:00
|
|
|
IF ( ionode ) THEN
|
2004-03-24 17:36:50 +08:00
|
|
|
!
|
2003-12-10 22:57:07 +08:00
|
|
|
CALL seqopn( iunocc, TRIM( prefix )//'.occup', 'FORMATTED', exst )
|
|
|
|
READ( UNIT = iunocc, FMT = * ) ns
|
|
|
|
CLOSE( UNIT = iunocc, STATUS = 'KEEP' )
|
2004-03-24 17:36:50 +08:00
|
|
|
!
|
|
|
|
ELSE
|
|
|
|
!
|
|
|
|
ns(:,:,:,:) = 0.D0
|
|
|
|
!
|
2003-12-10 22:57:07 +08:00
|
|
|
END IF
|
2004-03-24 17:36:50 +08:00
|
|
|
!
|
2005-01-06 00:43:26 +08:00
|
|
|
CALL reduce( ( ldim * ldim * nspin * nat ), ns )
|
2003-12-10 22:57:07 +08:00
|
|
|
CALL poolreduce( ( ldim * ldim * nspin * nat ), ns )
|
2004-03-24 17:36:50 +08:00
|
|
|
!
|
2004-12-21 23:28:01 +08:00
|
|
|
nsnew = ns
|
2004-03-24 17:36:50 +08:00
|
|
|
!
|
2003-12-10 22:57:07 +08:00
|
|
|
END IF
|
|
|
|
!
|
|
|
|
ELSE
|
2004-03-24 17:36:50 +08:00
|
|
|
!
|
2005-05-27 20:52:50 +08:00
|
|
|
! ... Case c): the potential is built from a superposition
|
2005-01-07 20:57:41 +08:00
|
|
|
! ... of atomic charges contained in the array rho_at
|
2005-05-27 20:52:50 +08:00
|
|
|
!
|
2003-12-10 22:57:07 +08:00
|
|
|
IF ( startingpot == 'file' .AND. .NOT. exst ) &
|
2005-05-27 20:52:50 +08:00
|
|
|
WRITE( stdout, '(5X,"Cannot read rho : file not found")' )
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
2004-08-23 14:51:19 +08:00
|
|
|
WRITE( UNIT = stdout, &
|
|
|
|
FMT = '(/5X,"Initial potential from superposition of free atoms")' )
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
2003-12-10 22:57:07 +08:00
|
|
|
! ... in the lda+U case set the initial value of ns
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
2003-12-10 22:57:07 +08:00
|
|
|
IF ( lda_plus_u ) THEN
|
2004-12-21 23:28:01 +08:00
|
|
|
!
|
2005-01-06 00:43:26 +08:00
|
|
|
CALL init_ns()
|
2004-12-21 23:28:01 +08:00
|
|
|
!
|
|
|
|
nsnew = ns
|
2003-12-10 22:57:07 +08:00
|
|
|
!
|
|
|
|
END IF
|
|
|
|
!
|
|
|
|
CALL atomic_rho( rho, nspin )
|
|
|
|
!
|
|
|
|
IF ( input_drho /= ' ' ) THEN
|
|
|
|
!
|
|
|
|
IF ( lsda ) CALL errore( 'potinit', ' lsda not allowed in drho', 1 )
|
2004-08-23 14:51:19 +08:00
|
|
|
!
|
2003-12-10 22:57:07 +08:00
|
|
|
CALL io_pot( -1, input_drho, vr, nspin )
|
2004-08-23 14:51:19 +08:00
|
|
|
!
|
2005-01-06 00:43:26 +08:00
|
|
|
WRITE( UNIT = stdout, &
|
|
|
|
FMT = '(/5X,"a scf correction to at. rho is read from", A20)' ) &
|
2003-12-10 22:57:07 +08:00
|
|
|
input_drho
|
2004-08-23 14:51:19 +08:00
|
|
|
!
|
2004-12-21 23:28:01 +08:00
|
|
|
rho = rho + vr
|
2003-12-10 22:57:07 +08:00
|
|
|
!
|
|
|
|
END IF
|
|
|
|
!
|
|
|
|
!
|
2005-05-27 20:52:50 +08:00
|
|
|
END IF
|
|
|
|
!
|
|
|
|
! ... check the integral of the starting charge
|
|
|
|
!
|
|
|
|
IF ( nspin == 2 ) THEN
|
2005-03-29 17:05:42 +08:00
|
|
|
!
|
2005-05-27 20:52:50 +08:00
|
|
|
charge = SUM ( rho (:, 1:nspin) ) * omega / ( nr1 * nr2 * nr3 )
|
|
|
|
!
|
|
|
|
ELSE
|
|
|
|
!
|
|
|
|
charge = SUM ( rho (:, 1) ) * omega / ( nr1 * nr2 * nr3 )
|
2003-12-10 22:57:07 +08:00
|
|
|
!
|
|
|
|
END IF
|
|
|
|
!
|
2005-05-27 20:56:18 +08:00
|
|
|
call reduce (1, charge)
|
|
|
|
!
|
2005-05-27 20:52:50 +08:00
|
|
|
IF ( lscf .AND. ABS( charge - nelec ) / charge > 1.D-6 ) THEN
|
|
|
|
!
|
|
|
|
WRITE( stdout, &
|
|
|
|
'(/,5X,"starting charge ",F10.5,", renormalised to ",F10.5)') &
|
|
|
|
charge, nelec
|
|
|
|
!
|
|
|
|
rho = rho / charge * nelec
|
|
|
|
!
|
|
|
|
ELSE IF ( .NOT. lscf .AND. ABS( charge - nelec ) / charge > 1.D-6 ) THEN
|
|
|
|
!
|
|
|
|
CALL errore ( 'potinit', 'starting and expected charges differ', 1 )
|
|
|
|
!
|
|
|
|
END IF
|
|
|
|
!
|
|
|
|
! ... compute the potential and store it in vr
|
|
|
|
!
|
|
|
|
CALL v_of_rho( rho, rho_core, nr1, nr2, nr3, nrx1, nrx2, nrx3, &
|
|
|
|
nrxx, nl, ngm, gstart, nspin, g, gg, alat, omega, &
|
|
|
|
ehart, etxc, vtxc, etotefield, charge, vr )
|
|
|
|
!
|
2003-12-10 22:57:07 +08:00
|
|
|
! ... define the total local potential (external+scf)
|
|
|
|
!
|
|
|
|
CALL set_vrs( vrs, vltot, vr, nrxx, nspin, doublegrid )
|
|
|
|
!
|
|
|
|
! ... write on output the parameters used in the lda+U calculation
|
|
|
|
!
|
|
|
|
IF ( lda_plus_u ) THEN
|
|
|
|
!
|
2005-01-06 00:43:26 +08:00
|
|
|
WRITE( stdout, '(/5X,"Parameters of the lda+U calculation:")')
|
|
|
|
WRITE( stdout, '(5X,"Number of iteration with fixed ns =",I3)') &
|
2003-12-10 22:57:07 +08:00
|
|
|
niter_with_fixed_ns
|
2005-01-06 00:43:26 +08:00
|
|
|
WRITE( stdout, '(5X,"Starting ns and Hubbard U :")')
|
2004-12-21 23:28:01 +08:00
|
|
|
!
|
|
|
|
CALL write_ns()
|
2003-12-10 22:57:07 +08:00
|
|
|
!
|
|
|
|
END IF
|
|
|
|
!
|
2005-02-25 22:51:41 +08:00
|
|
|
IF ( report /= 0 .AND. noncolin .AND. lscf ) CALL report_mag()
|
2005-01-06 00:43:26 +08:00
|
|
|
!
|
2003-12-10 22:57:07 +08:00
|
|
|
RETURN
|
|
|
|
!
|
|
|
|
END SUBROUTINE potinit
|