! ! 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 . ! ! !----------------------------------------------------------------------- PROGRAM vdw !----------------------------------------------------------------------- ! ! Program for calculating dynamic polarizability of a generic finite system ! (e.g., atoms, molecules,...) using TF-vW approximation. ! The two basic steps are: ! 1) read the output file produced by pw. ! 2) calculate the effective potential ! 3) solve the modified Sternheimer equation to determine density response, ! hence polarizability ! USE kinds, ONLY : DP USE environment, ONLY : environment_start USE mp_global, ONLY : mp_startup USE io_global, ONLY : ionode, stdout USE pwcom USE scf, ONLY : rho USE uspp, ONLY : nkb, vkb USE phcom USE qpoint, ONLY : nksq USE control_vdw, ONLY : thresh_veff USE check_stop, ONLY : check_stop_init ! IMPLICIT NONE REAL (kind=DP) :: charge, vstart INTEGER :: i ! ! initialise environment ! #ifdef __PARA CALL mp_startup ( ) #endif CALL environment_start ( 'VdW' ) ! IF ( ionode ) CALL input_from_file ( ) ! CALL vdw_init ( ) ! CALL check_stop_init() ! !!! workaround to prevent array mismatch: vkb is allocated in allocate_nlpot, !!! called by read_file, called by vdw_init, with nkb set to the "correct" !!! value, but we need nkb=0 and vkb array consistently allocated nkb = 0 DEALLOCATE (vkb) ALLOCATE (vkb(npwx,nkb)) !!! nbnd = 1 nbndx = 4 * nbnd nksq = 1 ! ! Allocate needed variables ! CALL allocate_vdw() ! ! Start polarizability calculation ! WRITE( stdout,'(/,5x,"Effective Potential Calculation",/)') ! ! Calculate the effective potential ! CALL eff_pot (rho%of_r, nspin, alat, omega, & charge, vstart, thresh_veff) ! WRITE( stdout,'(/,5x,"End of Effective Potential Calculation",/)') ! ! Electric field calculation ! lgamma = .true. CALL allocate_phq() ALLOCATE(ikks(nksq), ikqs(nksq)) ikks(1)=1 ikqs(1)=1 ! call newd() ! don't remember why this routine is here. But it seem not to do ! any thing. ! call openfilq() ! WRITE( stdout,'(/,5x,"Frequency Dependent Polarizability Calculation",/)') ! ! i = nfs freq_loop : DO WHILE ( i >= 1 ) ! CALL solve_e_vdw ( fiu(i) ) IF ( convt ) CALL polariz_vdw ( fiu(i) ) i = i - 1 ! ENDDO freq_loop ! WRITE( stdout,'(/,5x,"End of Frequency Dependent Polarizability Calculation",/)') ! CALL deallocate_phq() ! ! WRITE( stdout, '(/,5x,"End of vdW calculation")') ! ! CALL clean_pw( .true. ) ! CALL stop_vdw() ! CALL stop_clock( 'VdW' ) ! END PROGRAM vdw ! !----------------------------------------------------------------------- SUBROUTINE vdw_init ( ) !----------------------------------------------------------------------- ! ! This subroutine reads the data for the output file produced by pw.x ! ! DESCRIPTION of the INPUT: see file Docs/INPUT_VdW ! USE kinds, ONLY : DP USE cell_base, ONLY : bg USE ener, ONLY : ef USE ions_base, ONLY : nat, ntyp=>nsp, ityp, tau USE gvect USE grid_dimensions USE vlocal, ONLY : strf USE io_files, ONLY : tmp_dir, prefix, trimcheck USE io_global, ONLY : ionode, ionode_id, stdout USE mp, ONLY : mp_bcast USE parser, ONLY : read_line USE freq_ph USE control_vdw IMPLICIT NONE INTEGER :: plot_num, kpoint, kband, spin_component, ios, flen LOGICAL :: stm_wfc_matching, lsign REAL(DP) :: emin, emax, sample_bias, z, dz, epsilon ! directory for temporary files CHARACTER(len=256) :: outdir CHARACTER(len=256) :: input_line CHARACTER(len=80) :: card CHARACTER(len=1), EXTERNAL :: capital LOGICAL :: tend LOGICAL :: end_of_file INTEGER :: i NAMELIST / inputvdw / outdir, prefix, tr2_vdw, thresh_veff, nmix_vdw, & al_mix_vdw, niter_vdw ! prefix : the prefix of files produced by pwscf ! outdir : directory where input, output, temporary files reside ! tr2_vdw : convergence threshold ! thresh_veff : thresh_hold for iterative optimization of Veff ! nmix_vdw : number of previous iterations used in mixing ! al_mix_vdw : the mixing parameter ! niter_vdw : maximum number of iterations ! ! set default values for variables in namelist ! CALL start_clock( 'vdw_init' ) ! prefix = 'pwscf' outdir = './' tr2_vdw = 1.d-12 thresh_veff = 4.d-3 nmix_vdw = 4 al_mix_vdw = 0.1d0 niter_vdw = 50 ! IF ( ionode ) THEN ! ! reading the namelist inputpp ! READ (5, inputvdw, err = 200, iostat = ios) 200 CALL errore ('vdw', 'reading inputvdw namelist', abs (ios) ) tmp_dir = trimcheck ( outdir ) ! ! reading frequencies ! READ (5, *, err = 10, iostat = ios) card READ (5, *, err = 10, iostat = ios) nfs IF ( nfs > nfsmax ) & CALL errore ('extract', 'nfs too large', 1 ) DO i = 1, nfs READ (5, *, err = 10, iostat = ios) fiu(i) ENDDO 10 CALL errore ('extract', 'error or eof while reading frequencies', abs(ios) ) ENDIF ! ! ! ... Broadcast variables ! CALL mp_bcast( tmp_dir, ionode_id ) CALL mp_bcast( prefix, ionode_id ) CALL mp_bcast( nfs, ionode_id ) CALL mp_bcast( fiu, ionode_id ) CALL mp_bcast( thresh_veff, ionode_id ) CALL mp_bcast( tr2_vdw, ionode_id ) CALL mp_bcast( nmix_vdw, ionode_id ) CALL mp_bcast( al_mix_vdw, ionode_id ) CALL mp_bcast( niter_vdw, ionode_id ) ! ! no task specified: do nothing and return ! ! ! Now allocate space for pwscf variables, read and check them. ! CALL read_file ( ) CALL openfil_pp ( ) CALL struc_fact (nat, tau, ntyp, ityp, ngm, g, bg, nr1, nr2, nr3, & strf, eigts1, eigts2, eigts3) CALL init_us_1 ( ) ! CALL stop_clock( 'vdw_init' ) ! END SUBROUTINE vdw_init