quantum-espresso/CPV/runsd.f90

192 lines
6.2 KiB
Fortran

!
! Copyright (C) 2002-2005 FPMD-CPV groups
! 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 .
!
! ---------------------------------------------------------------------- !
MODULE runsd_module
! ---------------------------------------------------------------------- !
USE kinds, ONLY: DP
IMPLICIT NONE
SAVE
PRIVATE
REAL(DP), PRIVATE :: old_clock_value = 0.0d0
PUBLIC :: runsd
! ---------------------------------------------------------------------- !
CONTAINS
! ---------------------------------------------------------------------- !
! -----------------------------------------------------------------------
! BEGIN manual
SUBROUTINE runsd(tortho, tprint, tforce, rhoe, desc, atoms_0, &
bec, becdr, eigr, ei1, ei2, ei3, sfac, c0, cm, cp, cdesc, tcel, ht0, occ, ei, &
vpot, doions, edft, maxnstep, sdthr )
! this routine computes the electronic ground state via steepest descent
! END manual
! ... declare modules
USE energies, ONLY: dft_energy_type, print_energies
USE wave_functions, ONLY: update_wave_functions
USE check_stop, ONLY: check_stop_now
USE io_global, ONLY: ionode
USE io_global, ONLY: stdout
USE cell_module, ONLY: boxdimensions
USE wave_types, ONLY: wave_descriptor
USE potentials, ONLY: kspotential
USE atoms_type_module, ONLY: atoms_type
USE runcp_module, ONLY: runcp
USE phase_factors_module, ONLY: strucf, phfacs
USE charge_types, ONLY: charge_descriptor
USE control_flags, ONLY: force_pairing
use grid_dimensions, only: nr1, nr2, nr3
USE reciprocal_vectors, ONLY: mill_l
USE gvecp, ONLY: ngm
IMPLICIT NONE
! ... declare subroutine arguments
LOGICAL :: tortho, tprint, tforce, tcel, doions
TYPE (atoms_type), INTENT(INOUT) :: atoms_0
COMPLEX(DP), INTENT(INOUT) :: c0(:,:,:,:), cm(:,:,:,:), cp(:,:,:,:)
TYPE (wave_descriptor) :: cdesc
REAL(DP) :: rhoe(:,:,:,:)
COMPLEX(DP) :: sfac(:,:)
TYPE (charge_descriptor) :: desc
COMPLEX(DP) :: eigr(:,:)
COMPLEX(DP) :: ei1(:,:)
COMPLEX(DP) :: ei2(:,:)
COMPLEX(DP) :: ei3(:,:)
TYPE (boxdimensions), INTENT(INOUT) :: ht0
REAL(DP) :: occ(:,:,:)
REAL(DP) :: bec(:,:)
REAL(DP) :: becdr(:,:,:)
TYPE (dft_energy_type) :: edft
REAL(DP) :: ei(:,:,:)
REAL(DP) :: vpot(:,:,:,:)
INTEGER :: maxnstep ! maximum number of iteration
REAL(DP) :: sdthr ! threshold for convergence
! ... declare other variables
LOGICAL :: ttsde, ttprint, ttforce, ttstress, gzero, ttortho
LOGICAL :: gammasym
REAL(DP) :: timepre, s0, s1, s2, s3, s4, s5, s6, seconds_per_iter
REAL(DP) :: eold, timerd, timeorto, ekinc, vnosee
REAL(DP) :: ekincs( cdesc%nspin )
REAL(DP) :: ekinc_old, emin, demin
INTEGER :: ispin, nspin, iter, ierr
REAL(DP), EXTERNAL :: cclock
! ... end of declarations
! ----------------------------------------------
nspin = cdesc%nspin
doions = .FALSE.
eold = 1.0d10 ! a large number
timerd = 0
timeorto = 0
ttsde = .TRUE.
ttprint = .FALSE.
ttforce = .FALSE.
ttstress = .FALSE.
ttortho = .TRUE.
vnosee = 0.0d0
gzero = cdesc%gzero
gammasym = cdesc%gamma
IF( force_pairing ) &
CALL errore( ' runsd ', ' force pairing not implemented ', 1 )
IF( ionode ) THEN
WRITE( stdout,'(/,12X,"Steepest Descent Optimizations for electron, starting ...")' )
WRITE( stdout,'( 12X,"iter erho derho ekinc seconds")' )
END IF
old_clock_value = cclock()
CALL phfacs( ei1, ei2, ei3, eigr, mill_l, atoms_0%taus, nr1, nr2, nr3, atoms_0%nat )
CALL strucf( sfac, ei1, ei2, ei3, mill_l, ngm )
STEEPEST_DESCENT: DO iter = 1, maxnstep
s1 = cclock()
CALL kspotential( 1, ttprint, ttforce, ttstress, rhoe, desc, atoms_0, &
bec, becdr, eigr, ei1, ei2, ei3, sfac, c0, cdesc, tcel, ht0, &
occ, vpot, edft, timepre )
s2 = cclock()
CALL runcp( ttprint, ttortho, ttsde, cm, c0, cp, cdesc, vpot, eigr, occ, ekincs, timerd, &
timeorto, ht0, ei, bec, vnosee)
ekinc = SUM( ekincs )
emin = edft%etot
demin = eold - emin
eold = emin
s0 = cclock()
seconds_per_iter = ( s0 - old_clock_value )
old_clock_value = s0
IF( ionode ) THEN
WRITE( stdout,113) iter, emin, demin, ekinc, seconds_per_iter
113 FORMAT(10X,I5,2X,F14.6,2X,3D12.4)
END IF
CALL update_wave_functions(cm, c0, cp, cdesc)
s6 = cclock()
! ... check for exit
IF (check_stop_now()) THEN
EXIT STEEPEST_DESCENT
END IF
IF( ekinc .LT. sdthr ) THEN
IF(ionode) WRITE( stdout,fmt="(12X,'runsd: convergence achieved succesfully')")
doions = .TRUE.
EXIT STEEPEST_DESCENT
END IF
ekinc_old = ekinc
END DO STEEPEST_DESCENT
! ... set wave functions velocity to 0
cm = c0
IF( tforce ) THEN
atoms_0%for = 0.0d0
CALL kspotential( 1, ttprint, tforce, ttstress, rhoe, desc, &
atoms_0, bec, becdr, eigr, ei1, ei2, ei3, sfac, c0, cdesc, tcel, ht0, occ, vpot, edft, timepre )
IF(ionode ) THEN
WRITE( stdout,fmt="(12X,'runsd: fion and edft calculated = ',F14.6)") edft%etot
END IF
END IF
IF( (iter .GT. maxnstep) .AND. ionode) THEN
WRITE( stdout,fmt= &
"(12X,'runsd: convergence not achieved, maximum number of iteration exceeded')")
END IF
RETURN
END SUBROUTINE runsd
! ---------------------------------------------------------------------- !
END MODULE runsd_module
! ---------------------------------------------------------------------- !