quantum-espresso/PW/minimization_routines.f90

185 lines
5.3 KiB
Fortran

!
! Copyright (C) 2001-2003 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 .
!
!
!--------------------------------------------------------------------------
MODULE minimization_routines
!---------------------------------------------------------------------------
!
USE kinds, ONLY : DP
USE constants, ONLY : AU, eV_to_kelvin, eps32
USE neb_variables, ONLY : pos, ds, grad, norm_grad
USE basic_algebra_routines, ONLY : norm
!
IMPLICIT NONE
!
CONTAINS
!
! ... steepest descent
!
!----------------------------------------------------------------------
SUBROUTINE steepest_descent( index )
!----------------------------------------------------------------------
!
IMPLICIT NONE
!
INTEGER, INTENT(IN) :: index
!
!
IF ( norm_grad(index) >= eps32 ) THEN
!
pos(:,index) = pos(:,index) - ds * grad(:,index)
!
END IF
!
RETURN
!
END SUBROUTINE steepest_descent
!
! ... Molecular Dynamics based algorithms
! ... velocity Verlet and quick min
!
!----------------------------------------------------------------------
SUBROUTINE velocity_Verlet_first_step( index )
!----------------------------------------------------------------------
!
USE neb_variables, ONLY : vel, mass
!
IMPLICIT NONE
!
INTEGER, INTENT(IN) :: index
!
!
vel(:,index) = vel(:,index) - ds / 2.D0 * grad(:,index) / mass(:)
pos(:,index) = pos(:,index) + ds * vel(:,index)
!
RETURN
!
END SUBROUTINE velocity_Verlet_first_step
!
!
!----------------------------------------------------------------------
SUBROUTINE velocity_Verlet_second_step( index )
!----------------------------------------------------------------------
!
USE neb_variables, ONLY : vel, mass, damp, ldamped_dyn, lmol_dyn
!
IMPLICIT NONE
!
INTEGER, INTENT(IN) :: index
!
!
IF ( ldamped_dyn ) THEN
!
vel(:,index) = damp * ( vel(:,index) - &
ds / 2.D0 * grad(:,index) / mass(:) )
!
ELSE IF ( lmol_dyn ) THEN
!
vel(:,index) = vel(:,index) - ds / 2.D0 * grad(:,index) / mass(:)
!
END IF
!
RETURN
!
END SUBROUTINE velocity_Verlet_second_step
!
!----------------------------------------------------------------------
SUBROUTINE quick_min_second_step( index )
!----------------------------------------------------------------------
!
USE neb_variables, ONLY : vel, mass, dim
!
IMPLICIT NONE
!
INTEGER, INTENT(IN) :: index
REAL (KIND=DP), DIMENSION(dim) :: force_versor
REAL (KIND=DP) :: vel_component
!
!
vel(:,index) = vel(:,index) - ds / 2.D0 * grad(:,index) / mass(:)
!
IF ( norm_grad(index) >= eps32 ) THEN
!
force_versor = - grad(:,index) / norm_grad(index)
!
vel_component = DOT_PRODUCT( vel(:,index) , force_versor )
!
IF ( vel_component > 0.D0 ) THEN
!
vel(:,index) = vel_component * force_versor
!
ELSE
!
vel(:,index) = 0.D0
!
END IF
!
ELSE
!
vel(:,index) = 0.D0
!
END IF
!
RETURN
!
END SUBROUTINE quick_min_second_step
!
! ... routine for fixed temperature dynamics
!
!----------------------------------------------------------------------
SUBROUTINE thermalization( N_in , N_fin )
!----------------------------------------------------------------------
!
USE neb_variables, ONLY : vel, mass, temp, temp_req, deg_of_freedom
!
IMPLICIT NONE
!
INTEGER, INTENT(IN) :: N_in, N_fin
REAL (KIND=DP) :: local_temp
INTEGER :: image
!
!
temp = 0.D0
!
DO image = N_in, N_fin
!
local_temp = DOT_PRODUCT( mass(:) * vel(:,image) , &
vel(:,image) ) / REAL( deg_of_freedom )
!
temp = temp + local_temp
!
vel(:,image) = vel(:,image) * SQRT( temp_req / local_temp )
!
END DO
!
temp = temp / REAL( N_fin - N_in )
!
#if defined ( _DEBUG ) || ( _DEBUG_THERMALIZATION )
!
PRINT *, "temperature before thermalization", temp * AU * eV_to_kelvin
!
temp = 0.D0
!
DO image = N_in, N_fin
!
temp = temp + DOT_PRODUCT( mass(:) * vel(:,image) , vel(:,image) )
!
END DO
!
temp = temp / REAL( ( N_fin - N_in ) * deg_of_freedom )
!
PRINT *, "temperature after thermalization", temp * AU * eV_to_kelvin
!
#endif
!
RETURN
!
END SUBROUTINE thermalization
!
END MODULE minimization_routines