mirror of https://gitlab.com/QEF/q-e.git
A new code (cpvib.x) for calculating normal modes, Born charge tensors
and infrared cross-section for isolated molecules/cluster in vacuum. It uses the CP as an underlying DFT engine, and a the frozen-phonon approach for calculating the energy Hessian. [silviu] git-svn-id: http://qeforge.qe-forge.org/svn/q-e/trunk/espresso@2512 c92efa57-630b-4861-b058-cf58834340f0
This commit is contained in:
parent
06380219a4
commit
cf3931813d
|
@ -0,0 +1,215 @@
|
|||
# Makefile for CP/FPMD
|
||||
|
||||
include ../make.sys
|
||||
|
||||
CPVIB_OBJ = \
|
||||
vibrations.o \
|
||||
environment.o \
|
||||
rdiagh.o \
|
||||
rdiaghg.o \
|
||||
read_input_vib.o \
|
||||
viblib.o
|
||||
|
||||
CP_OBJS = \
|
||||
../CPV/atoms_type.o \
|
||||
../CPV/band_type.o \
|
||||
../CPV/bessel.o \
|
||||
../CPV/berryion.o \
|
||||
../CPV/bforceion.o \
|
||||
../CPV/blacs.o \
|
||||
../CPV/brillouin.o \
|
||||
../CPV/cg.o \
|
||||
../CPV/cg_sub.o \
|
||||
../CPV/cglib.o \
|
||||
../CPV/chargedensity.o \
|
||||
../CPV/chargemix.o \
|
||||
../CPV/charge_types.o \
|
||||
../CPV/chi2.o \
|
||||
../CPV/compute_fes_grads.o \
|
||||
../CPV/compute_scf.o \
|
||||
../CPV/cp_emass.o \
|
||||
../CPV/cp_fpmd.o \
|
||||
../CPV/cp_restart.o \
|
||||
../CPV/cplib.o \
|
||||
../CPV/cpr_mod.o \
|
||||
../CPV/cpr.o \
|
||||
../CPV/cprsub.o \
|
||||
../CPV/crayfft.o \
|
||||
../CPV/dealloc.o \
|
||||
../CPV/diis.o \
|
||||
../CPV/dipol_matrix.o \
|
||||
../CPV/dforceb.o \
|
||||
../CPV/efermi.o \
|
||||
../CPV/efield.o \
|
||||
../CPV/eigsp.o \
|
||||
../CPV/eigs0.o \
|
||||
../CPV/electrons.o \
|
||||
../CPV/emptystates.o \
|
||||
../CPV/ensemble_dft.o \
|
||||
../CPV/exch_corr.o \
|
||||
../CPV/fftdrv.o \
|
||||
../CPV/fft.o \
|
||||
../CPV/fields_type.o \
|
||||
../CPV/fnl.o \
|
||||
../CPV/forces.o \
|
||||
../CPV/fromscra.o \
|
||||
../CPV/greenf.o \
|
||||
../CPV/grid.o \
|
||||
../CPV/gsmesh.o \
|
||||
../CPV/gtable.o \
|
||||
../CPV/guess.o \
|
||||
../CPV/init.o \
|
||||
../CPV/init_run.o \
|
||||
../CPV/input.o \
|
||||
../CPV/interfaces_main.o \
|
||||
../CPV/interfaces.o \
|
||||
../CPV/ions.o \
|
||||
../CPV/ions_positions.o \
|
||||
../CPV/ksstates.o \
|
||||
../CPV/macdep.o \
|
||||
../CPV/main.o \
|
||||
../CPV/mainvar.o \
|
||||
../CPV/main_loops.o \
|
||||
../CPV/cplib_meta.o \
|
||||
../CPV/metaxc.o \
|
||||
../CPV/modules.o \
|
||||
../CPV/move_electrons.o \
|
||||
../CPV/nl_base.o \
|
||||
../CPV/nlcc.o \
|
||||
../CPV/nl.o \
|
||||
../CPV/optical.o \
|
||||
../CPV/ortho_base.o \
|
||||
../CPV/ortho.o \
|
||||
../CPV/para.o \
|
||||
../CPV/path_routines.o \
|
||||
../CPV/periodic.o \
|
||||
../CPV/phasefactor.o \
|
||||
../CPV/polarization.o \
|
||||
../CPV/potentials.o \
|
||||
../CPV/print_out.o \
|
||||
../CPV/problem_size.o \
|
||||
../CPV/pseudo_base.o \
|
||||
../CPV/pseudopot.o \
|
||||
../CPV/qmatrixd.o \
|
||||
../CPV/qqberry.o \
|
||||
../CPV/read_pseudo.o \
|
||||
../CPV/redis.o \
|
||||
../CPV/restart.o \
|
||||
../CPV/restart_sub.o \
|
||||
../CPV/rsmesh.o \
|
||||
../CPV/runcg_ion.o \
|
||||
../CPV/runcg.o \
|
||||
../CPV/runcp.o \
|
||||
../CPV/rundiis.o \
|
||||
../CPV/runsd.o \
|
||||
../CPV/scalapack.o \
|
||||
../CPV/smcp.o \
|
||||
../CPV/smd_modules.o \
|
||||
../CPV/smd.o \
|
||||
../CPV/smlam.o \
|
||||
../CPV/spharmonic.o \
|
||||
../CPV/spline.o \
|
||||
../CPV/stop_run.o \
|
||||
../CPV/stress.o \
|
||||
../CPV/turbo.o \
|
||||
../CPV/util.o \
|
||||
../CPV/vanderwaals.o \
|
||||
../CPV/cp_version.o \
|
||||
../CPV/wannier_base.o \
|
||||
../CPV/wannier.o \
|
||||
../CPV/waveinit.o \
|
||||
../CPV/wave.o \
|
||||
../CPV/wave_types.o \
|
||||
../CPV/wf.o \
|
||||
../CPV/$(WRAPPERS)
|
||||
|
||||
LOBJS = \
|
||||
../CPV/adjef.o \
|
||||
../CPV/entropy.o \
|
||||
../CPV/forceconv.o \
|
||||
../CPV/geninv.o \
|
||||
../CPV/indices.o \
|
||||
../CPV/miller.o
|
||||
|
||||
MODULES = \
|
||||
../Modules/atom.o \
|
||||
../Modules/autopilot.o \
|
||||
../Modules/basic_algebra_routines.o \
|
||||
../Modules/berry_phase.o \
|
||||
../Modules/cell_base.o \
|
||||
../Modules/check_stop.o \
|
||||
../Modules/clocks.o \
|
||||
../Modules/coarsegrained_vars.o \
|
||||
../Modules/constants.o \
|
||||
../Modules/constraints_module.o \
|
||||
../Modules/control_flags.o \
|
||||
../Modules/descriptors.o \
|
||||
../Modules/electrons_base.o \
|
||||
../Modules/energies.o \
|
||||
../Modules/fft_base.o \
|
||||
../Modules/fft_scalar.o \
|
||||
../Modules/fft_types.o \
|
||||
../Modules/functionals.o \
|
||||
../Modules/griddim.o \
|
||||
../Modules/input_parameters.o \
|
||||
../Modules/io_base.o \
|
||||
../Modules/io_files.o \
|
||||
../Modules/io_global.o \
|
||||
../Modules/ions_base.o \
|
||||
../Modules/ions_nose.o \
|
||||
../Modules/kind.o \
|
||||
../Modules/mp_buffers.o \
|
||||
../Modules/mp_global.o \
|
||||
../Modules/mp_wave.o \
|
||||
../Modules/mp.o \
|
||||
../Modules/parallel_types.o \
|
||||
../Modules/path_base.o \
|
||||
../Modules/path_formats.o \
|
||||
../Modules/path_variables.o \
|
||||
../Modules/path_opt_routines.o \
|
||||
../Modules/path_io_routines.o \
|
||||
../Modules/path_reparametrisation.o \
|
||||
../Modules/parallel_include.o \
|
||||
../Modules/parameters.o \
|
||||
../Modules/parser.o \
|
||||
../Modules/printout_base.o \
|
||||
../Modules/pseudo_types.o \
|
||||
../Modules/ptoolkit.o \
|
||||
../Modules/read_cards.o \
|
||||
../Modules/read_namelists.o \
|
||||
../Modules/readpseudo.o \
|
||||
../Modules/recvec.o \
|
||||
../Modules/shmem_include.o \
|
||||
../Modules/sic.o \
|
||||
../Modules/smallbox.o \
|
||||
../Modules/splinelib.o \
|
||||
../Modules/stick_base.o \
|
||||
../Modules/uspp.o \
|
||||
../Modules/version.o \
|
||||
../Modules/wavefunctions.o \
|
||||
../Modules/wave_base.o \
|
||||
../Modules/timestep.o \
|
||||
../Modules/xml_io_base.o
|
||||
|
||||
WRAPPERS = wrapper.o
|
||||
|
||||
all : cpvib.x
|
||||
cpvib: cpvib.x
|
||||
|
||||
cpvib.x : $(CP_OBJS) $(CPVIB_OBJ) $(LOBJS) $(LIBOBJS) ../CPV/cp.x vibstart.o
|
||||
$(MPIF90) $(LDFLAGS) -g -o cpvib.x -I../CPV \
|
||||
vibstart.o $(CP_OBJS) $(CPVIB_OBJ) $(LOBJS) $(MODULES) \
|
||||
../flib/eispack.o $(LIBOBJS) $(LIBS)
|
||||
- ( cd ../bin ; ln -fs ../CPVIB/cpvib.x . )
|
||||
|
||||
cpvib_version.o : cpvibver.h
|
||||
|
||||
cpvibver.h :
|
||||
echo "CHARACTER(LEN=70), PARAMETER :: version_date = '"`date`"'" \
|
||||
> cpvibver.h
|
||||
|
||||
clean :
|
||||
- /bin/rm -f cpvib.x *.o *.mod version.h *.i core* *.F90 fort* \
|
||||
*.cpp *.d work.pc *.s
|
||||
|
||||
include make.depend
|
|
@ -0,0 +1,212 @@
|
|||
!
|
||||
! 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 environment
|
||||
!==-----------------------------------------------------------------------==!
|
||||
|
||||
USE kinds
|
||||
USE io_files, ONLY: crash_file, crashunit, &
|
||||
stop_file, stopunit
|
||||
|
||||
IMPLICIT NONE
|
||||
SAVE
|
||||
|
||||
PRIVATE
|
||||
|
||||
REAL(DP) :: start_seconds
|
||||
REAL(DP) :: start_cclock_val
|
||||
|
||||
PUBLIC :: environment_start
|
||||
PUBLIC :: environment_end
|
||||
PUBLIC :: opening_date_and_time, closing_date_and_time
|
||||
PUBLIC :: start_cclock_val
|
||||
|
||||
!==-----------------------------------------------------------------------==!
|
||||
CONTAINS
|
||||
!==-----------------------------------------------------------------------==!
|
||||
|
||||
|
||||
SUBROUTINE environment_start( )
|
||||
|
||||
USE io_global, ONLY: stdout, ionode
|
||||
USE mp_global, ONLY: mpime, nproc
|
||||
USE parser, ONLY: int_to_char
|
||||
use para_mod, ONLY: me, node
|
||||
use mp, only: mp_env
|
||||
USE cp_version
|
||||
|
||||
LOGICAL :: texst
|
||||
REAL(DP) :: elapsed_seconds, cclock
|
||||
EXTERNAL elapsed_seconds, cclock
|
||||
INTEGER :: nchar
|
||||
CHARACTER(LEN=80) :: uname
|
||||
CHARACTER(LEN=80) :: version_str
|
||||
|
||||
|
||||
CALL init_clocks( .TRUE. )
|
||||
CALL start_clock( 'CP' )
|
||||
|
||||
start_seconds = elapsed_seconds()
|
||||
start_cclock_val = cclock( )
|
||||
|
||||
version_str = TRIM (version_number) // " - " // TRIM (version_date)
|
||||
|
||||
! ... Temporary for para_mod
|
||||
|
||||
me = mpime + 1
|
||||
|
||||
! ... search for file CRASH and delete it
|
||||
|
||||
IF( ionode ) THEN
|
||||
INQUIRE( FILE=TRIM(crash_file), EXIST=texst )
|
||||
IF( texst ) THEN
|
||||
OPEN( UNIT=crashunit, FILE=TRIM(crash_file), STATUS='OLD' )
|
||||
CLOSE( UNIT=crashunit, STATUS='DELETE' )
|
||||
END IF
|
||||
END IF
|
||||
|
||||
! ... each processor other than me=1 opens its own standard output file,
|
||||
! ... this is mainly for debugging, usually only ionode writes to stdout
|
||||
|
||||
IF( .NOT. ionode ) THEN
|
||||
|
||||
uname = 'out.' // int_to_char( mpime )
|
||||
nchar = INDEX(uname,' ') - 1
|
||||
!
|
||||
! useful for debugging purposes:
|
||||
! open( unit = stdout, file = uname(1:nchar),status='unknown')
|
||||
open( unit = stdout, file='/dev/null', status='unknown' )
|
||||
|
||||
END IF
|
||||
|
||||
! ... Temporary for para_mod
|
||||
|
||||
if (me < 10) then
|
||||
write(node,'(i1,2x)') me
|
||||
else if (me < 100) then
|
||||
write(node,'(i2,1x)') me
|
||||
else if (me < 1000) then
|
||||
write(node,'(i3)') me
|
||||
else
|
||||
call errore('startup','wow, >1000 nodes !!',nproc)
|
||||
end if
|
||||
|
||||
CALL opening_date_and_time( version_str )
|
||||
|
||||
#if defined __MPI
|
||||
|
||||
WRITE( stdout,100) nproc, mpime
|
||||
100 FORMAT(3X,'MPI Parallel Build',/,3X,'Tasks =',I5,' This task id =',I5)
|
||||
|
||||
#else
|
||||
|
||||
WRITE( stdout,100)
|
||||
100 FORMAT(3X,'Serial Build')
|
||||
|
||||
#endif
|
||||
|
||||
RETURN
|
||||
END SUBROUTINE environment_start
|
||||
|
||||
!==-----------------------------------------------------------------------==!
|
||||
|
||||
SUBROUTINE environment_end( )
|
||||
|
||||
USE io_global, ONLY: stdout, ionode
|
||||
|
||||
REAL(DP) :: total_seconds
|
||||
|
||||
REAL(DP) :: elapsed_seconds
|
||||
EXTERNAL elapsed_seconds
|
||||
|
||||
IF(ionode) THEN
|
||||
WRITE( stdout,*)
|
||||
END IF
|
||||
|
||||
CALL print_clock( 'CP' )
|
||||
CALL stop_clock( 'CP' )
|
||||
|
||||
CALL closing_date_and_time( )
|
||||
|
||||
total_seconds = elapsed_seconds() - start_seconds
|
||||
|
||||
IF(ionode) THEN
|
||||
WRITE( stdout,'(A,F7.1)') ' ELAPSED SECONDS: ', total_seconds
|
||||
WRITE( stdout,'(A)') ' JOB DONE.'
|
||||
WRITE( stdout,3335)
|
||||
END IF
|
||||
3335 FORMAT('=',78('-'),'=')
|
||||
|
||||
RETURN
|
||||
END SUBROUTINE environment_end
|
||||
|
||||
!==-----------------------------------------------------------------------==!
|
||||
|
||||
SUBROUTINE opening_date_and_time( version_str )
|
||||
|
||||
USE io_global, ONLY: stdout, ionode
|
||||
|
||||
CHARACTER(LEN=*), INTENT(IN) :: version_str
|
||||
CHARACTER(LEN=9) :: cdate, ctime
|
||||
CHARACTER(LEN=80) :: time_str
|
||||
|
||||
CALL date_and_tim(cdate, ctime)
|
||||
time_str = 'This run was started on: ' // ctime // ' ' // cdate
|
||||
|
||||
! ... write program heading
|
||||
|
||||
|
||||
IF(ionode) THEN
|
||||
WRITE( stdout,3331)
|
||||
WRITE( stdout,3332) version_str
|
||||
WRITE( stdout,3331)
|
||||
WRITE( stdout,3334) time_str
|
||||
END IF
|
||||
|
||||
3331 FORMAT('=',78('-'),'=')
|
||||
3332 FORMAT( /, 5X,'Ab-initio DFT calculation of normal modes for',/&
|
||||
& ,5X,'molecules and clusters in vacuum. The CP code is used as',/&
|
||||
& ,5x,'the undelying DFT egine.'//&
|
||||
& ,5X,'Version: ',A60,/&
|
||||
& ,5x,'Authors of the normal-modes code: Silviu Zilberman',//&
|
||||
& ,5X,'Authors of the CP code: Alfredo Pasquarello, Kari Laasonen, Andrea Trave, Roberto Car,',/&
|
||||
& ,5X,' Paolo Giannozzi, Nicola Marzari, Carlo Cavazzoni, Guido Chiarotti,',/&
|
||||
& ,5X,' Sandro Scandolo, Paolo Focher, Gerardo Ballabio, and others',/)
|
||||
|
||||
3334 FORMAT(/,3X,A60,/)
|
||||
RETURN
|
||||
END SUBROUTINE opening_date_and_time
|
||||
|
||||
!==-----------------------------------------------------------------------==!
|
||||
|
||||
SUBROUTINE closing_date_and_time( )
|
||||
|
||||
USE io_global, ONLY: stdout, ionode
|
||||
|
||||
CHARACTER(LEN=9) :: cdate, ctime
|
||||
CHARACTER(LEN=80) :: time_str
|
||||
|
||||
CALL date_and_tim(cdate, ctime)
|
||||
|
||||
time_str = 'This run was terminated on: ' // ctime // ' ' // cdate
|
||||
|
||||
IF( ionode ) THEN
|
||||
WRITE( stdout,*)
|
||||
WRITE( stdout,3334) time_str
|
||||
WRITE( stdout,3335)
|
||||
END IF
|
||||
|
||||
3334 FORMAT(3X,A60,/)
|
||||
3335 FORMAT('=',78('-'),'=')
|
||||
|
||||
RETURN
|
||||
END SUBROUTINE closing_date_and_time
|
||||
|
||||
!==-----------------------------------------------------------------------==!
|
||||
END MODULE environment
|
||||
!==-----------------------------------------------------------------------==!
|
|
@ -0,0 +1,101 @@
|
|||
!
|
||||
! Copyright (C) 2001-2005 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 .
|
||||
!
|
||||
!#include "f_defs.h"
|
||||
!
|
||||
!----------------------------------------------------------------------------
|
||||
SUBROUTINE rdiagh( n, h, ldh, e, v )
|
||||
!----------------------------------------------------------------------------
|
||||
!
|
||||
! ... calculates all the eigenvalues and eigenvectors of a complex
|
||||
! ... hermitean matrix H . On output, the matrix is unchanged
|
||||
!
|
||||
!USE kinds, ONLY : 8
|
||||
!USE mp_global, ONLY : npool, me_pool, root_pool, intra_pool_comm, my_image_id
|
||||
!USE mp, ONLY : mp_bcast
|
||||
!
|
||||
IMPLICIT NONE
|
||||
!
|
||||
! ... on INPUT
|
||||
!
|
||||
INTEGER :: n, & ! dimension of the matrix to be diagonalized
|
||||
ldh ! leading dimension of h, as declared in
|
||||
! the calling pgm unit
|
||||
REAL (KIND=8) :: h(ldh,n) ! matrix to be diagonalized
|
||||
!
|
||||
! ... on OUTPUT
|
||||
!
|
||||
REAL (KIND=8) :: e(n) ! eigenvalues
|
||||
REAL (KIND=8) :: v(ldh,n) ! eigenvectors (column-wise)
|
||||
!
|
||||
!
|
||||
!CALL start_clock( 'rdiagh' )
|
||||
!
|
||||
CALL rdiagh_lapack( )
|
||||
!
|
||||
!CALL stop_clock( 'rdiagh' )
|
||||
!
|
||||
RETURN
|
||||
!
|
||||
CONTAINS
|
||||
!
|
||||
! ... internal procedures
|
||||
!
|
||||
!-----------------------------------------------------------------------
|
||||
SUBROUTINE rdiagh_lapack( )
|
||||
!-----------------------------------------------------------------------
|
||||
!
|
||||
IMPLICIT NONE
|
||||
!
|
||||
! ... local variables (LAPACK version)
|
||||
!
|
||||
INTEGER :: lwork, nb, info
|
||||
INTEGER, EXTERNAL :: ILAENV
|
||||
! ILAENV returns optimal block size "nb"
|
||||
REAL (KIND=8), ALLOCATABLE :: work(:)
|
||||
!
|
||||
!
|
||||
! ... check for the block size
|
||||
!
|
||||
nb = ILAENV( 1, 'DSYTRD', 'U', n, - 1, - 1, - 1 )
|
||||
!
|
||||
IF ( nb < 1 ) nb = MAX( 1, n )
|
||||
!
|
||||
lwork = ( nb + 3 ) * n
|
||||
!
|
||||
! ... only the first processor diagonalize the matrix
|
||||
!
|
||||
!IF ( me_pool == root_pool ) THEN
|
||||
!
|
||||
! ... allocate workspace
|
||||
!
|
||||
v = h
|
||||
!
|
||||
ALLOCATE( work( lwork ) )
|
||||
!
|
||||
CALL DSYEV( 'V', 'U', n, v, ldh, e, work, lwork, info )
|
||||
!
|
||||
if (abs(info).ne.0) then
|
||||
!CALL errore( 'rdiagh', 'info =/= 0', ABS( info ) )
|
||||
write (6,*) 'error: rdiagh - info =/= 0 ', ABS( info )
|
||||
end if
|
||||
!
|
||||
! ... deallocate workspace
|
||||
!
|
||||
DEALLOCATE( work )
|
||||
!
|
||||
!END IF
|
||||
!
|
||||
!CALL mp_bcast( e, root_pool, intra_pool_comm )
|
||||
!CALL mp_bcast( v, root_pool, intra_pool_comm )
|
||||
!
|
||||
RETURN
|
||||
!
|
||||
END SUBROUTINE rdiagh_lapack
|
||||
!
|
||||
END SUBROUTINE rdiagh
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
!
|
||||
! Copyright (C) 2005 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 .
|
||||
!
|
||||
!#include "f_defs.h"
|
||||
!
|
||||
!----------------------------------------------------------------------------
|
||||
SUBROUTINE rdiaghg( n, m, h, s, ldh, e, v )
|
||||
!----------------------------------------------------------------------------
|
||||
!
|
||||
! ... calculates eigenvalues and eigenvectors of the generalized problem
|
||||
! ... Hv=eSv, with H symmetric matrix, S overlap matrix .
|
||||
! ... On output both matrix are unchanged
|
||||
! ... Uses LAPACK routines
|
||||
!
|
||||
!USE kinds, ONLY : 8
|
||||
!USE mp, ONLY : mp_bcast
|
||||
!USE mp_global, ONLY : npool, me_pool, root_pool, intra_pool_comm, my_image_id
|
||||
!
|
||||
IMPLICIT NONE
|
||||
!
|
||||
! ... on INPUT
|
||||
!
|
||||
INTEGER :: n, m, ldh
|
||||
! dimension of the matrix to be diagonalized
|
||||
! number of eigenstates to be calculated
|
||||
! leading dimension of h, as declared in the calling pgm unit
|
||||
REAL(KIND=8) :: h(ldh,n)
|
||||
! matrix to be diagonalized
|
||||
REAL(KIND=8) :: s(ldh,n)
|
||||
! overlap matrix
|
||||
!
|
||||
! ... on OUTPUT
|
||||
!
|
||||
REAL(KIND=8) :: e(n)
|
||||
! eigenvalues
|
||||
REAL(KIND=8) :: v(ldh,m)
|
||||
! eigenvectors (column-wise)
|
||||
!
|
||||
! ... LOCAL variables
|
||||
!
|
||||
INTEGER :: lwork, nb, ILAENV, mm, info
|
||||
! ILAENV returns optimal block size "nb"
|
||||
! mm = number of calculated eigenvectors
|
||||
EXTERNAL ILAENV
|
||||
INTEGER, ALLOCATABLE :: iwork(:), ifail(:)
|
||||
REAL(KIND=8), ALLOCATABLE :: sdum(:,:), hdum(:,:), work(:)
|
||||
LOGICAL :: all_eigenvalues
|
||||
!
|
||||
!
|
||||
!CALL start_clock( 'cdiaghg' )
|
||||
!
|
||||
all_eigenvalues = ( m == n )
|
||||
!
|
||||
! ... check for optimal block size
|
||||
!
|
||||
nb = ILAENV( 1, 'DSYTRD', 'U', n, -1, -1, -1 )
|
||||
!
|
||||
IF ( nb < 1 .OR. nb >= n ) THEN
|
||||
!
|
||||
lwork = 8 * n
|
||||
!
|
||||
ELSE
|
||||
!
|
||||
lwork = ( nb + 3 ) * n
|
||||
!
|
||||
END IF
|
||||
!
|
||||
! ... allocate workspace
|
||||
!
|
||||
ALLOCATE( work( lwork ) )
|
||||
ALLOCATE( sdum( ldh, n ) )
|
||||
!
|
||||
IF ( .NOT. all_eigenvalues ) THEN
|
||||
!
|
||||
ALLOCATE( hdum( ldh, n ) )
|
||||
ALLOCATE( iwork( 5*n ) )
|
||||
ALLOCATE( ifail( n ) )
|
||||
!
|
||||
END IF
|
||||
!
|
||||
! ... input s and (see below) h are copied so that they are not destroyed
|
||||
!
|
||||
sdum = s
|
||||
!
|
||||
! ... only the first processor diagonalize the matrix
|
||||
!
|
||||
!IF ( me_pool == root_pool ) THEN
|
||||
!
|
||||
IF ( all_eigenvalues ) THEN
|
||||
!
|
||||
! ... calculate all eigenvalues
|
||||
!
|
||||
v(:,1:n) = h(:,:)
|
||||
!
|
||||
#if defined (__AIX)
|
||||
!
|
||||
! ... there is a name conflict between essl and lapack ...
|
||||
!
|
||||
CALL DSYGV( 1, v, ldh, sdum, ldh, e, v, ldh, n, work, lwork )
|
||||
!
|
||||
info = 0
|
||||
!
|
||||
#else
|
||||
CALL DSYGV( 1, 'V', 'U', n, v, ldh, sdum, ldh, e, work, &
|
||||
lwork, info )
|
||||
!
|
||||
#endif
|
||||
ELSE
|
||||
!
|
||||
! ... calculate only m lowest eigenvalues
|
||||
!
|
||||
hdum = h
|
||||
!
|
||||
CALL DSYGVX( 1, 'V', 'I', 'U', n, hdum, ldh, sdum, ldh, &
|
||||
0.D0, 0.D0, 1, m, 0.D0, mm, e, v, ldh, work, lwork, &
|
||||
iwork, ifail, info )
|
||||
!
|
||||
END IF
|
||||
!
|
||||
!CALL errore( 'rdiaghg', 'info =/= 0', ABS( info ) )
|
||||
if (info.ne.0) then
|
||||
write (6,*) 'error: rdiaghg - info =/= 0i ',ABS( info )
|
||||
end if
|
||||
!
|
||||
!END IF
|
||||
!
|
||||
! ... broadcast eigenvectors and eigenvalues to all other processors
|
||||
!
|
||||
!CALL mp_bcast( e, root_pool, intra_pool_comm )
|
||||
!CALL mp_bcast( v, root_pool, intra_pool_comm )
|
||||
!
|
||||
! ... deallocate workspace
|
||||
!
|
||||
IF ( .NOT. all_eigenvalues ) THEN
|
||||
!
|
||||
DEALLOCATE( ifail )
|
||||
DEALLOCATE( iwork )
|
||||
DEALLOCATE( hdum )
|
||||
!
|
||||
END IF
|
||||
!
|
||||
DEALLOCATE( sdum )
|
||||
DEALLOCATE( work )
|
||||
!
|
||||
!CALL stop_clock( 'cdiaghg' )
|
||||
!
|
||||
RETURN
|
||||
!
|
||||
END SUBROUTINE rdiaghg
|
|
@ -0,0 +1,138 @@
|
|||
!
|
||||
! Copyright (C) 2001-2005 QUANTUM-ESPRESSO 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 .
|
||||
!
|
||||
#include "f_defs.h"
|
||||
!
|
||||
!----------------------------------------------------------------------------
|
||||
SUBROUTINE read_input_vib()
|
||||
!----------------------------------------------------------------------------
|
||||
!
|
||||
! This routine reads the control variables for the program cpvib.
|
||||
! from prefix.vib.inp input file.
|
||||
!
|
||||
! ... modules
|
||||
!
|
||||
USE io_files, ONLY : outdir, prefix
|
||||
USE io_global, ONLY : ionode, ionode_id, stdout
|
||||
USE kinds, ONLY : DP
|
||||
USE mp, ONLY : mp_bcast
|
||||
USE vibrations, ONLY : delta, save_freq, &
|
||||
trans_inv_max_iter, trans_inv_conv_thr, vib_restart_mode, &
|
||||
trans_inv_flag, trans_rot_inv_flag, animate
|
||||
!
|
||||
IMPLICIT NONE
|
||||
!
|
||||
! ... local variables
|
||||
!
|
||||
INTEGER :: ios, dirlen
|
||||
CHARACTER (LEN=256) :: restart_label, input_filename
|
||||
LOGICAL :: inp_file_exists
|
||||
!
|
||||
NAMELIST / INPUT_VIB / delta, save_freq, trans_inv_max_iter, &
|
||||
trans_inv_conv_thr, restart_label, trans_inv_flag,trans_rot_inv_flag, &
|
||||
animate
|
||||
!
|
||||
IF ( ionode ) THEN
|
||||
!
|
||||
! Set input file name
|
||||
!
|
||||
dirlen = INDEX(outdir,' ') - 1
|
||||
input_filename = TRIM(prefix)//'.vib.inp'
|
||||
input_filename = outdir(1:dirlen) // '/' // input_filename
|
||||
WRITE (stdout,*) 'Input information is read from:', input_filename
|
||||
!
|
||||
! ... Open input file
|
||||
!
|
||||
INQUIRE (FILE = input_filename, EXIST = inp_file_exists)
|
||||
IF ( .NOT. inp_file_exists) &
|
||||
CALL errore( 'read_input_vib', 'input file absent ', 1 )
|
||||
OPEN( 99 , FILE = input_filename , STATUS = 'old' )
|
||||
!
|
||||
! ... set default values for variables in namelist
|
||||
!
|
||||
delta = 0.05
|
||||
save_freq = 1
|
||||
trans_inv_flag = .TRUE.
|
||||
trans_rot_inv_flag = .TRUE.
|
||||
trans_inv_max_iter = 50
|
||||
trans_inv_conv_thr = 1.0D-15
|
||||
vib_restart_mode = 2
|
||||
restart_label = 'auto'
|
||||
animate = .FALSE.
|
||||
!
|
||||
! ... reading the namelist input_vib
|
||||
!
|
||||
READ( 99, input_vib, ERR = 200, IOSTAT = ios )
|
||||
!
|
||||
200 CALL errore( 'readin_input_vib', 'reading input_vib namelist', ABS(ios) )
|
||||
!
|
||||
! ... Check all namelist variables
|
||||
!
|
||||
IF (delta <= 0.D0) &
|
||||
CALL errore (' readin_input_vib', ' Wrong delta ', 1)
|
||||
!
|
||||
IF (trans_inv_max_iter <= 0.D0) &
|
||||
CALL errore (' readin_input_vib', ' Wrong trans_inv_max_iter ', 1)
|
||||
!
|
||||
IF (trans_inv_conv_thr <= 0.D0) &
|
||||
CALL errore (' readin_input_vib', ' Wrong trans_inv_conv_thr ', 1)
|
||||
!
|
||||
SELECT CASE ( TRIM( restart_label ) )
|
||||
CASE( 'from_scratch' )
|
||||
vib_restart_mode = 0
|
||||
CASE ( 'restart' )
|
||||
vib_restart_mode = 1
|
||||
CASE ( 'auto' )
|
||||
vib_restart_mode = 2
|
||||
CASE DEFAULT
|
||||
CALL errore( 'read_input_vib ', &
|
||||
'unknown vib_restart_mode ' // TRIM( restart_label ), 1 )
|
||||
END SELECT
|
||||
END IF
|
||||
!
|
||||
! ... Broadcasting input variables
|
||||
!
|
||||
CALL mp_bcast( delta, ionode_id )
|
||||
CALL mp_bcast( save_freq, ionode_id )
|
||||
CALL mp_bcast( trans_inv_max_iter, ionode_id )
|
||||
CALL mp_bcast( trans_inv_conv_thr, ionode_id )
|
||||
CALL mp_bcast( trans_inv_flag, ionode_id )
|
||||
CALL mp_bcast( trans_rot_inv_flag, ionode_id )
|
||||
CALL mp_bcast( vib_restart_mode, ionode_id )
|
||||
CALL mp_bcast( animate, ionode_id )
|
||||
!
|
||||
! ... Printing input data to stdout
|
||||
!
|
||||
IF (ionode) THEN
|
||||
WRITE (stdout,*) '------------------------------------------------------'
|
||||
WRITE (stdout,*) ' SUMMERY OF VIBRATIONAL INPUT VARIABLES: '
|
||||
WRITE (stdout,*) ''
|
||||
WRITE (stdout,101) delta
|
||||
WRITE (stdout,102) save_freq
|
||||
WRITE (stdout,103) trans_inv_flag
|
||||
WRITE (stdout,104) trans_inv_max_iter
|
||||
WRITE (stdout,105) trans_inv_conv_thr
|
||||
WRITE (stdout,106) trans_rot_inv_flag
|
||||
WRITE (stdout,107) restart_label
|
||||
WRITE (stdout,108) animate
|
||||
WRITE (stdout,*) '------------------------------------------------------'
|
||||
!
|
||||
101 FORMAT(3x,'delta = ',3x,f10.4)
|
||||
102 FORMAT(3x,'save_freq = ',3x,I10)
|
||||
103 FORMAT(3x,'trans_inv_flag = ',3x,L10)
|
||||
104 FORMAT(3x,'trans_inv_max_iter = ',3x,I10)
|
||||
105 FORMAT(3x,'trans_inv_conv_thr = ',3x,D10.4)
|
||||
106 FORMAT(3x,'trans_rot_inv_flag = ',3x,L10)
|
||||
107 FORMAT(3x,'restart_label = ',3x,A10)
|
||||
108 FORMAT(3x,'animate = ',3x,L10)
|
||||
!
|
||||
CLOSE(99)
|
||||
END IF
|
||||
!
|
||||
RETURN
|
||||
!
|
||||
END SUBROUTINE read_input_vib
|
|
@ -0,0 +1,328 @@
|
|||
!
|
||||
! Copyright (C) 2001-2005 QUANTUM-ESPRESSO 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 .
|
||||
!
|
||||
!-------------------------------------------------------------------------
|
||||
!
|
||||
! Auxiliary functions for the vibrational analysis
|
||||
!
|
||||
!-------------------------------------------------------------------------
|
||||
|
||||
SUBROUTINE print_matrix (matrix, dim1, dim2, title, filep)
|
||||
!
|
||||
! ... modules
|
||||
!
|
||||
USE kinds, ONLY: DP
|
||||
!
|
||||
IMPLICIT NONE
|
||||
!
|
||||
! ... input variables
|
||||
!
|
||||
INTEGER, INTENT(IN) :: dim1, dim2, filep
|
||||
CHARACTER (len=*), INTENT(IN) :: title
|
||||
REAL (KIND=DP), INTENT(IN) :: matrix(dim1,dim2)
|
||||
!
|
||||
! ... local variables
|
||||
!
|
||||
INTEGER :: i,j
|
||||
!
|
||||
! ...
|
||||
!
|
||||
WRITE (filep,*)
|
||||
WRITE (filep,*) TRIM(title)
|
||||
WRITE (filep,*)
|
||||
DO i=1,dim1
|
||||
DO j=1,dim2
|
||||
WRITE (filep,FMT='(F12.5,3X)',ADVANCE='NO') matrix(i,j)
|
||||
END DO
|
||||
WRITE (filep,*)
|
||||
END DO
|
||||
WRITE (filep,*)
|
||||
!
|
||||
RETURN
|
||||
END SUBROUTINE print_matrix
|
||||
!
|
||||
!
|
||||
! ----------------------------------------------
|
||||
!
|
||||
!
|
||||
SUBROUTINE write_xyz(tau,free_text,position_in_file,file_name)
|
||||
!
|
||||
! Printout of the coordinates in an xyz format
|
||||
! tau - coordinates
|
||||
! free_text - text for the second line of output
|
||||
! position_in_file - either 'APPEND' (for an xyz animation),
|
||||
! 'REWIND' to overwrite, or 'ASIS'
|
||||
!
|
||||
! ... modules
|
||||
!
|
||||
USE constants, ONLY : bohr_radius_angs
|
||||
USE input_parameters, ONLY : atom_label
|
||||
USE io_files, ONLY : iunxyz
|
||||
USE ions_base, ONLY : nat, ityp
|
||||
USE kinds, ONLY : DP
|
||||
!
|
||||
IMPLICIT NONE
|
||||
!
|
||||
! ... input variables
|
||||
!
|
||||
CHARACTER (LEN=*), INTENT(IN) :: position_in_file, free_text
|
||||
CHARACTER (LEN=*), INTENT(IN) :: file_name
|
||||
REAL (KIND=DP), INTENT(IN) :: tau(3,nat)
|
||||
!
|
||||
! ... local variables
|
||||
!
|
||||
INTEGER :: atom
|
||||
CHARACTER (LEN=*), PARAMETER :: xyz_fmt = "(A2,3(2X,F14.10))"
|
||||
|
||||
OPEN( UNIT = iunxyz, FILE = file_name, &
|
||||
STATUS = "UNKNOWN", ACTION = "WRITE", &
|
||||
POSITION = TRIM(position_in_file))
|
||||
!
|
||||
WRITE( UNIT = iunxyz, FMT = '(I5,/)' ) nat
|
||||
WRITE( UNIT = iunxyz, FMT = '(A ,/)' ) free_text
|
||||
!
|
||||
DO atom = 1, nat
|
||||
!
|
||||
WRITE( UNIT = iunxyz, FMT = xyz_fmt ) &
|
||||
TRIM( atom_label( ityp( atom ) ) ), &
|
||||
tau(1,atom)*bohr_radius_angs, &
|
||||
tau(2,atom)*bohr_radius_angs, &
|
||||
tau(3,atom)*bohr_radius_angs
|
||||
!
|
||||
END DO
|
||||
!
|
||||
CLOSE(iunxyz)
|
||||
!
|
||||
RETURN
|
||||
END SUBROUTINE write_xyz
|
||||
!
|
||||
!
|
||||
! ----------------------------------------------
|
||||
!
|
||||
!
|
||||
SUBROUTINE calculate_dipole (dipole, dipole_moment,tau)
|
||||
!
|
||||
! Driver routine for the calculation of the dipole moment.
|
||||
! Currently it uses only subroutine 'poles' from cplib.f90
|
||||
! It could easily be extended to use Wannier functions as well.
|
||||
!
|
||||
! ... modules
|
||||
!
|
||||
USE cp_main_variables, ONLY : irb, eigrb, bec, rhor, rhog, rhos
|
||||
USE electrons_base, ONLY : nspin
|
||||
USE energies, ONLY : ekin, enl
|
||||
USE ions_base, ONLY : nat
|
||||
USE kinds, ONLY : DP
|
||||
USE wavefunctions_module, ONLY : c0
|
||||
USE uspp, ONLY : becsum
|
||||
!
|
||||
IMPLICIT NONE
|
||||
!
|
||||
! ... input variables
|
||||
!
|
||||
REAL (KIND=DP), INTENT(IN) :: tau(3,nat)
|
||||
!
|
||||
! ... output variables
|
||||
!
|
||||
REAL (KIND=DP), INTENT(OUT) :: dipole(3), dipole_moment
|
||||
!
|
||||
! ... local variables
|
||||
!
|
||||
REAL (KIND=DP) :: quadrupole
|
||||
INTEGER :: nfi=10 ! ... dummy value
|
||||
LOGICAL :: ion_flag = .TRUE., coc_flag=.TRUE.
|
||||
!
|
||||
!
|
||||
!
|
||||
dipole = 0.0
|
||||
dipole_moment = 0.0
|
||||
rhor = 0.0
|
||||
rhog = 0.0
|
||||
rhos = 0.0
|
||||
!
|
||||
CALL rhoofr(nfi,c0,irb,eigrb,bec,becsum,rhor,rhog,rhos,enl,ekin)
|
||||
IF (nspin.EQ.2) THEN
|
||||
rhor(:,1)=rhor(:,1)+rhor(:,2)
|
||||
END IF
|
||||
CALL poles (dipole_moment,dipole,quadrupole,rhor(:,1),&
|
||||
ion_flag,tau,coc_flag)
|
||||
!
|
||||
! STILL HAVE TO ADD IN THE WANNIER BASED DIPOLE
|
||||
! AS AN ALTERNATIVE WAY OF DOING THE CALCULATION
|
||||
!
|
||||
RETURN
|
||||
END SUBROUTINE calculate_dipole
|
||||
!
|
||||
!
|
||||
! ----------------------------------------------
|
||||
!
|
||||
!
|
||||
SUBROUTINE orthonormalize(M,dim1,dim2)
|
||||
!
|
||||
! modified Gram-Schimd - orthogonalizing for
|
||||
! dim1 vectors of length dim2
|
||||
!
|
||||
!
|
||||
! ... modules
|
||||
!
|
||||
USE kinds, ONLY : DP
|
||||
!
|
||||
IMPLICIT NONE
|
||||
!
|
||||
!... input variables
|
||||
!
|
||||
INTEGER, INTENT(IN) :: dim1,dim2 !dimensions of input matrix
|
||||
REAL(KIND=DP),INTENT(INOUT):: M(dim1,dim2) !input matrix
|
||||
!
|
||||
!... local variables
|
||||
!
|
||||
REAL (KIND=DP) :: t(dim2,dim2), z
|
||||
INTEGER :: i,j,k
|
||||
!
|
||||
t=0.0
|
||||
!
|
||||
DO k=1,dim2
|
||||
!
|
||||
! ... normalizing vector k
|
||||
z=0.0
|
||||
DO i=1,dim1
|
||||
z=z+M(i,k)**2
|
||||
END DO
|
||||
t(k,k)=SQRT(z)
|
||||
M(:,k)=M(:,k)/t(k,k)
|
||||
!
|
||||
! ... removing the projection of vector k
|
||||
! ... from the remaining vectors k+1...dim2
|
||||
!
|
||||
DO j=k+1,dim2
|
||||
z=0.0
|
||||
DO i=1,dim1
|
||||
z=z+M(i,j)*M(i,k)
|
||||
END DO
|
||||
!
|
||||
t(k,j)=z
|
||||
!
|
||||
DO i=1,dim1
|
||||
M(i,j)=M(i,j)-t(k,j)*M(i,k)
|
||||
END DO
|
||||
END DO
|
||||
!
|
||||
END DO
|
||||
!
|
||||
RETURN
|
||||
END SUBROUTINE orthonormalize
|
||||
!
|
||||
!
|
||||
! ----------------------------------------------
|
||||
!
|
||||
!
|
||||
SUBROUTINE symmetrize_matrix(M, dim)
|
||||
!
|
||||
! IMPOSING SYMMETRY ON MATRIX M
|
||||
! M(i,j)==M(j,i)
|
||||
!
|
||||
! ... modules
|
||||
!
|
||||
USE kinds, ONLY : DP
|
||||
!
|
||||
IMPLICIT NONE
|
||||
!
|
||||
! ... input/output variables
|
||||
!
|
||||
INTEGER, INTENT(IN) :: dim
|
||||
REAL (KIND=DP), INTENT(INOUT) :: M(dim,dim)
|
||||
!
|
||||
! ... local variables
|
||||
!
|
||||
INTEGER :: i,j
|
||||
REAL (KIND=DP) :: sum
|
||||
!
|
||||
!
|
||||
DO i=1,dim
|
||||
DO j = i+1,dim
|
||||
sum = (M(i,j)+M(j,i))/2
|
||||
M(i,j) = sum
|
||||
M(j,i) = sum
|
||||
END DO
|
||||
END DO
|
||||
!
|
||||
RETURN
|
||||
END SUBROUTINE symmetrize_matrix
|
||||
!
|
||||
!
|
||||
! ----------------------------------------------
|
||||
!
|
||||
!
|
||||
SUBROUTINE relax_wavefunction (fion)
|
||||
!
|
||||
! A DRIVER ROUTINE FOR WAVE FUNCTION RELAXATION
|
||||
!
|
||||
! ... modules
|
||||
!
|
||||
USE cell_base, ONLY : b1, b2, b3
|
||||
USE cg_module, ONLY : tcg
|
||||
USE control_flags, ONLY : tprnfor, thdyn
|
||||
USE cp_electronic_mass, ONLY : emass
|
||||
USE cp_main_variables, ONLY : eigr, ei1, ei2, ei3, &
|
||||
sfac, irb, eigrb, taub, nfi
|
||||
USE efield_module, ONLY : tefield, efield_update
|
||||
USE electrons_nose, ONLY : fccc
|
||||
USE energies, ONLY : eself, etot
|
||||
USE from_scratch_module, ONLY : from_scratch
|
||||
USE gvecs, ONLY : ngs
|
||||
USE ions_positions, ONLY : tau0
|
||||
USE kinds, ONLY : DP
|
||||
USE parameters, ONLY : natx
|
||||
USE phase_factors_module, ONLY : strucf
|
||||
USE reciprocal_vectors, ONLY : mill_l
|
||||
USE time_step, ONLY : dt2
|
||||
!
|
||||
IMPLICIT NONE
|
||||
!
|
||||
! ... input variables
|
||||
!
|
||||
REAL (KIND=DP) :: fion(3,natx)
|
||||
!
|
||||
! ... local variables
|
||||
!
|
||||
LOGICAL :: tfirst, tlast
|
||||
REAL (KIND=DP) :: enthal
|
||||
REAL (KIND=DP) :: dt2bye, enb, enbi, ccc
|
||||
!
|
||||
! ... for smooth restart in the new coordinates
|
||||
!
|
||||
dt2bye = dt2 / emass
|
||||
CALL initbox( tau0, taub, irb )
|
||||
CALL phbox( taub, eigrb )
|
||||
CALL phfac( tau0, ei1, ei2, ei3, eigr )
|
||||
CALL strucf( sfac, ei1, ei2, ei3, mill_l, ngs )
|
||||
IF ( thdyn ) CALL formf( tfirst, eself )
|
||||
IF (tefield ) CALL efield_update( eigr )
|
||||
!
|
||||
!... relax wavefunction in new position
|
||||
!
|
||||
IF (tcg) THEN
|
||||
tprnfor = .TRUE. ! ... atomic forces are calculated only at the
|
||||
! end of the wavefunction relaxation process
|
||||
CALL move_electrons( nfi, tfirst, tlast, b1, b2, b3, fion, &
|
||||
enthal, enb, enbi, fccc, ccc, dt2bye )
|
||||
tprnfor = .FALSE.
|
||||
ELSE
|
||||
tprnfor = .FALSE. ! ... no need to calculate atomic forces at
|
||||
! each step of the MD damped dynamics
|
||||
CALL cprmain ( tau0, fion, etot )
|
||||
!
|
||||
! ... one more scf step to get the forces on the nuclei
|
||||
!
|
||||
tprnfor = .TRUE.
|
||||
CALL move_electrons( nfi, tfirst, tlast, b1, b2, b3, fion, &
|
||||
enthal, enb, enbi, fccc, ccc, dt2bye )
|
||||
tprnfor = .FALSE.
|
||||
END IF
|
||||
!
|
||||
RETURN
|
||||
END SUBROUTINE relax_wavefunction
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,213 @@
|
|||
!
|
||||
! Copyright (C) 2002-2005 Quantum-ESPRESSO 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 .
|
||||
!
|
||||
#include "f_defs.h"
|
||||
!
|
||||
!==============================================================================
|
||||
! Program CPVIB (programmed by Silviu Zilberman)
|
||||
!
|
||||
! Calculates the vibrational modes, Born effective charges and infrared
|
||||
! cross-section for isolated molecules/clusters in vacuum.
|
||||
! The programs uses the CP code as the underlying DFT engine
|
||||
! for wave function relaxation (SCF) and the frozen phonon method for
|
||||
! construction of the energy hessian (dynamical matrix),
|
||||
! i.e. displace each atom in all three cartesian directions to construct
|
||||
! the numerical first derivative of the forces.
|
||||
!
|
||||
! The program uses two mandatory input files (optional files are discussed
|
||||
! further below):
|
||||
! 1. The regular CP input file, which presumably was used to generate a
|
||||
! ground state nuclear configuration (local minimum).
|
||||
! 2. A file "prefix.vib.inp", where prefix is defined in the CP input
|
||||
! file.
|
||||
!
|
||||
! prefix.vib.inp contains one name list:
|
||||
!
|
||||
! &INPUT_VIB
|
||||
! ...
|
||||
! /
|
||||
!
|
||||
! Parameters:
|
||||
!
|
||||
! delta real ( default = 0.05 )
|
||||
! displacement step, a uniform value for all atoms
|
||||
!
|
||||
! save_freq integer ( default = 1 )
|
||||
! Save restart information every save_freq displacements.
|
||||
! Since it is usually a small file, containing mainly
|
||||
! the intermediate hessian, it is suggested not to
|
||||
! change the default.
|
||||
! restart_label character ( default = 'auto' )
|
||||
! 'from_scratch': starts a new calculation
|
||||
! 'restart' : continue a previous calculation
|
||||
! a file 'prefix.vib.restart' must be present
|
||||
! 'auto' : if a file 'prefix.vib.restart' is present
|
||||
! the program will pick it up and continue
|
||||
! the previous calculation, or if absent,
|
||||
! it will start a new calculation
|
||||
!
|
||||
! trans_inv_flag logical ( default = .true. )
|
||||
! impose translational invariance on the energy hessian
|
||||
! to ensure that the modes associated with a rigid
|
||||
! translation would have zero frequency
|
||||
!
|
||||
! trans_inv_max_iter integer ( default = 50 )
|
||||
! the maximal number of steps in the iterative procedure
|
||||
! that removes the rigid translation modes
|
||||
!
|
||||
! trans_inv_conv_thr real ( default = 1.0D-15 )
|
||||
! the threshhold for convergence of the iterative procedure
|
||||
! for removal of the rigid translation modes
|
||||
!
|
||||
! trans_rot_inv_flag logical ( default = .true. )
|
||||
! remove also the rigid rotation modes
|
||||
!
|
||||
! animate logical ( default = .false. )
|
||||
! generate xyz animation files for all normal modes
|
||||
!
|
||||
! Additional information about the input/output files:
|
||||
!
|
||||
! 1. The program will look for the presence of 'prefix.vib.isotope' file.
|
||||
! It is a text file containing NAT lines, where NAT is the number of atoms.
|
||||
! Each line contains a single number, the mass of this particular atom
|
||||
! in the same order as in the CP input file. The masses are in AMU, i.e.
|
||||
! the hydrogen is ~1, carbon is 12 etc. If this file is present, these masses
|
||||
! are used in the calculation. If not, the default masses are used,
|
||||
! as specified in the CP input, and an isotopes file is created.
|
||||
! This is useful for testing the isotope shifts, without having to
|
||||
! redo the full calculation.
|
||||
!
|
||||
! 2. After the energy hessian is calculated, the program will write
|
||||
! the analysis results to 'prefix.vib.analysis'.
|
||||
! The minimal output is:
|
||||
! * raw (but symmetrized) hessian
|
||||
! * diagonal mass matrix
|
||||
! * harmonic frequencies and the associated effective
|
||||
! spring constant and effective mode mass
|
||||
! * raw Born charge tensors for each atom
|
||||
! * the sum over the Born charges (minus total system charge)
|
||||
! this quantity should ideally be zero (acoustic sum rule).
|
||||
! * infrared intensity of each normal mode.
|
||||
!
|
||||
! If trans_inv_flag==.true. then the same information as above is repeated
|
||||
! but this time with imposed translational invariance on the energy
|
||||
! hessian. In addition, the Born charges are symmetrized and
|
||||
! the acoustic sum rule is imposed.
|
||||
!
|
||||
! if trans_rot_inv_flag==.true. then also rotational modes are projected
|
||||
! out.
|
||||
!
|
||||
! A brief description of the methods:
|
||||
!
|
||||
! 1. The energy hessian is constructed by a simple difference formula for
|
||||
! the numerical first derivative of the forces.
|
||||
!
|
||||
! 2. The condition for translational invariance of the hessian is described
|
||||
! (for instance) in Gonze and Lee, Phys. Rev. B 55(16), 1997, 10355-10368.
|
||||
! However, simple enforcement of translational invariance breaks the
|
||||
! symmetry of the hessian. Here symmetrization and translational
|
||||
! invariance are repeatedly applied until convergence, i.e., until
|
||||
! the largest change in any matrix element of the hessian is smaller
|
||||
! than trans_inv_conv_thr parameter.
|
||||
! A more sophisticated and general algorithm was suggested by
|
||||
! Nicolas Mounet and Nicola Marzari (Ref. ???) and is already implemented
|
||||
! in QE.
|
||||
!
|
||||
! 3. The algorithm for removal of rotational rigid modes follows closely the
|
||||
! one implemented in Gaussian03 electronic structure package, as described
|
||||
! in their white papers (www.gaussian.com).
|
||||
!
|
||||
!
|
||||
! ==========================================================================
|
||||
! ==== units and constants ====
|
||||
! ==== ====
|
||||
! ==== 1 hartree = 1 a.u. ====
|
||||
! ==== 1 bohr radius = 1 a.u. = 0.529167 Angstrom ====
|
||||
! ==== 1 rydberg = 1/2 a.u. ====
|
||||
! ==== 1 electron volt = 1/27.212 a.u. ====
|
||||
! ==== 1 kelvin *k-boltzm. = 1/(27.212*11606) a.u.'='3.2e-6 a.u ====
|
||||
! ==== 1 second = 1/(2.4189)*1.e+17 a.u. ====
|
||||
! ==== 1 proton mass = 1822.89 a.u. ====
|
||||
! ==== 1 tera = 1.e+12 ====
|
||||
! ==== 1 pico = 1.e-12 ====
|
||||
! ==== 1 Volt / meter = 1/(5.1412*1.e+11) a.u. ====
|
||||
! ==========================================================================
|
||||
!
|
||||
!----------------------------------------------------------------------------
|
||||
PROGRAM cpvib
|
||||
!----------------------------------------------------------------------------
|
||||
!
|
||||
USE control_flags, ONLY : program_name
|
||||
USE environment, ONLY : environment_start
|
||||
USE input, ONLY : read_input_file, iosys_pseudo, iosys
|
||||
USE io_global, ONLY : io_global_start, io_global_getionode
|
||||
USE kinds, ONLY : DP
|
||||
USE mp_global, ONLY : mp_global_start
|
||||
USE mp, ONLY : mp_end, mp_start, mp_env
|
||||
USE vibrations, ONLY : start_vibrations, calc_hessian, &
|
||||
analysis, end_vibrations
|
||||
!
|
||||
IMPLICIT NONE
|
||||
!
|
||||
INTEGER :: mpime, nproc, gid, ionode_id, &
|
||||
restart_cyc_counter
|
||||
INTEGER, PARAMETER :: root = 0
|
||||
LOGICAL :: ionode
|
||||
REAL (KIND=DP) :: E_minus, dip_minus(3)
|
||||
!
|
||||
! ... program starts here
|
||||
!
|
||||
program_name = 'CP90'
|
||||
!
|
||||
! ... initialize MPI (parallel processing handling)
|
||||
!
|
||||
CALL mp_start()
|
||||
CALL mp_env( nproc, mpime, gid )
|
||||
CALL mp_global_start( root, mpime, gid, nproc )
|
||||
!
|
||||
! ... mpime = processor number, starting from 0
|
||||
! ... nproc = number of processors
|
||||
! ... gid = group index
|
||||
! ... root = index of the root processor
|
||||
!
|
||||
! ... initialize input output
|
||||
!
|
||||
CALL io_global_start( mpime, root )
|
||||
CALL io_global_getionode( ionode, ionode_id )
|
||||
!
|
||||
CALL environment_start( )
|
||||
!
|
||||
! ... readin the input file
|
||||
!
|
||||
CALL read_input_file()
|
||||
!
|
||||
! ... copy pseudopotential input parameter into internal variables
|
||||
! ... and read in pseudopotentials and wavefunctions files
|
||||
!
|
||||
CALL iosys_pseudo()
|
||||
!
|
||||
! ... copy-in input parameters from input_parameter module
|
||||
!
|
||||
CALL iosys()
|
||||
!
|
||||
CALL init_run()
|
||||
!
|
||||
! CALL memstat( 1 )
|
||||
!
|
||||
CALL read_input_vib()
|
||||
CALL start_vibrations(restart_cyc_counter, E_minus, dip_minus)
|
||||
CALL calc_hessian (restart_cyc_counter, E_minus, dip_minus)
|
||||
CALL analysis ()
|
||||
CALL end_vibrations()
|
||||
!
|
||||
CALL terminate_run()
|
||||
!
|
||||
CALL stop_run( .TRUE. )
|
||||
!
|
||||
STOP
|
||||
!
|
||||
END PROGRAM cpvib
|
|
@ -6,7 +6,7 @@ cd `echo $0 | sed 's/\(.*\)\/.*/\1/'` # extract pathname
|
|||
TOPDIR=`pwd`
|
||||
|
||||
for DIR in Modules clib PW CPV flib pwtools upftools PP PWCOND \
|
||||
Gamma PH D3 atomic Nmr
|
||||
Gamma PH D3 atomic Nmr CPVIB
|
||||
do
|
||||
# set inter-directory dependencies
|
||||
case $DIR in
|
||||
|
@ -17,6 +17,7 @@ do
|
|||
PP | PWCOND | Gamma | PH )
|
||||
DEPENDS="../include ../Modules ../PW ../iotk/src" ;;
|
||||
D3 | Nmr) DEPENDS="../include ../Modules ../PW ../PH ../iotk/src" ;;
|
||||
CPVIB ) DEPENDS="../include ../Modules ../iotk/src ../CPV"
|
||||
esac
|
||||
|
||||
# generate dependencies file
|
||||
|
|
|
@ -6,7 +6,7 @@ cd `echo $0 | sed 's/\(.*\)\/.*/\1/'` # extract pathname
|
|||
TOPDIR=`pwd`
|
||||
|
||||
for DIR in Modules clib PW CPV flib pwtools upftools PP PWCOND \
|
||||
Gamma PH D3 atomic Nmr
|
||||
Gamma PH D3 atomic Nmr CPVIB
|
||||
do
|
||||
# set inter-directory dependencies
|
||||
case $DIR in
|
||||
|
@ -17,6 +17,7 @@ do
|
|||
PP | PWCOND | Gamma | PH )
|
||||
DEPENDS="../include ../Modules ../PW ../iotk/src" ;;
|
||||
D3 | Nmr) DEPENDS="../include ../Modules ../PW ../PH ../iotk/src" ;;
|
||||
CPVIB ) DEPENDS="../include ../Modules ../iotk/src ../CPV"
|
||||
esac
|
||||
|
||||
# generate dependencies file
|
||||
|
|
Loading…
Reference in New Issue