mirror of https://gitlab.com/QEF/q-e.git
186 lines
5.9 KiB
Fortran
186 lines
5.9 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, atoms_0, bec, becdr, eigr, &
|
|
vkb, ei1, ei2, ei3, sfac, c0, cm, cp, cdesc, tcel, ht0, &
|
|
fi, 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 check_stop, ONLY: check_stop_now
|
|
USE io_global, ONLY: ionode
|
|
USE io_global, ONLY: stdout
|
|
USE cell_base, ONLY: boxdimensions
|
|
USE wave_types, ONLY: wave_descriptor
|
|
USE cp_interfaces, ONLY: kspotential
|
|
USE atoms_type_module, ONLY: atoms_type
|
|
USE cp_interfaces, ONLY: runcp, update_wave_functions, strucf, phfacs
|
|
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(:,:)
|
|
COMPLEX(DP) :: eigr(:,:)
|
|
COMPLEX(DP) :: vkb(:,:)
|
|
COMPLEX(DP) :: ei1(:,:)
|
|
COMPLEX(DP) :: ei2(:,:)
|
|
COMPLEX(DP) :: ei3(:,:)
|
|
TYPE (boxdimensions), INTENT(INOUT) :: ht0
|
|
REAL(DP) :: fi(:)
|
|
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) :: s0, s1, s2, s3, s4, s5, s6, seconds_per_iter
|
|
REAL(DP) :: eold, ekinc, fccc
|
|
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
|
|
ttsde = .TRUE.
|
|
ttprint = .FALSE.
|
|
ttforce = .FALSE.
|
|
ttstress = .FALSE.
|
|
ttortho = .TRUE.
|
|
fccc = 1.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 )
|
|
CALL prefor( eigr, vkb )
|
|
|
|
STEEPEST_DESCENT: DO iter = 1, maxnstep
|
|
|
|
s1 = cclock()
|
|
|
|
CALL kspotential( 1, ttprint, ttforce, ttstress, rhoe, atoms_0, &
|
|
bec, becdr, eigr, ei1, ei2, ei3, sfac, c0, cdesc, tcel, ht0, &
|
|
fi, vpot, edft )
|
|
|
|
s2 = cclock()
|
|
|
|
CALL runcp( ttprint, ttortho, ttsde, cm, c0, cp, vpot, vkb, fi, ekinc, ht0, ei, bec, fccc)
|
|
|
|
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 )
|
|
|
|
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, &
|
|
atoms_0, bec, becdr, eigr, ei1, ei2, ei3, sfac, c0, cdesc, tcel, ht0, fi, vpot, edft )
|
|
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
|
|
! ---------------------------------------------------------------------- !
|