Added Environ modules

This commit is contained in:
Edan Bainglass 2022-03-06 09:53:48 -06:00
parent 74df7a9ea7
commit b1875054f9
4 changed files with 690 additions and 0 deletions

View File

@ -0,0 +1,118 @@
#if defined (__ENVIRON)
!----------------------------------------------------------------------------------------
!>
!!
!----------------------------------------------------------------------------------------
MODULE environ_cp_module
!------------------------------------------------------------------------------------
!
USE environ_base_module, ONLY: environ
!
USE kinds, ONLY: DP
USE global_version, ONLY: version_number
USE io_global, ONLY: stdout
!
USE fft_base, ONLY: dfftp
!
USE electrons_base, ONLY: nspin, nelt
!
!------------------------------------------------------------------------------------
!
IMPLICIT NONE
!
PRIVATE
!
PUBLIC :: add_environ_potential, calc_environ_potential
!
!------------------------------------------------------------------------------------
CONTAINS
!------------------------------------------------------------------------------------
!>
!!
!------------------------------------------------------------------------------------
SUBROUTINE add_environ_potential(v)
!--------------------------------------------------------------------------------
!
IMPLICIT NONE
!
REAL(DP), INTENT(INOUT) :: v(dfftp%nnr, nspin)
!
INTEGER :: i
REAL(DP) :: dvtot(dfftp%nnr)
!
CHARACTER(LEN=80) :: sub_name = 'add_environ_potential'
!
!--------------------------------------------------------------------------------
!
dvtot = 0.5D0 * environ%main%get_dvtot(dfftp%nnr) ! Rydberg to Hartree
!
IF (nspin .EQ. 1) THEN
!
!$omp parallel do
DO i = 1, dfftp%nnr
v(i, 1) = v(i, 1) + dvtot(i)
END DO
!$omp end parallel do
!
ELSE IF (nspin .EQ. 2) THEN
!
!$omp parallel do
DO i = 1, dfftp%nnr
v(i, 1) = v(i, 1) + dvtot(i)
v(i, 2) = v(i, 2) + dvtot(i)
END DO
!$omp end parallel do
!
END IF
!
!--------------------------------------------------------------------------------
END SUBROUTINE add_environ_potential
!------------------------------------------------------------------------------------
!>
!!
!------------------------------------------------------------------------------------
SUBROUTINE calc_environ_potential(rhoin, nfi)
!--------------------------------------------------------------------------------
!
IMPLICIT NONE
!
REAL(DP), INTENT(IN) :: rhoin(dfftp%nnr, nspin)
INTEGER, INTENT(IN) :: nfi
!
LOGICAL :: update_venviron = .FALSE.
REAL(DP) :: rhoaux(dfftp%nnr)
!
CHARACTER(LEN=80) :: sub_name = 'calc_environ_potential'
!
!--------------------------------------------------------------------------------
! update electrons-related quantities in environ
!
rhoaux = rhoin(:, 1)
!
IF (version_number == '6.3') THEN
IF (nspin == 2) rhoaux = rhoaux + rhoin(:, 2)
END IF
!
CALL environ%main%update_electrons(dfftp%nnr, rhoaux, REAL(nelt, DP))
!
!--------------------------------------------------------------------------------
! Environ contribution to the local potential
!
update_venviron = nfi > environ%setup%get_nskip() .OR. environ%setup%is_restart()
!
IF (update_venviron .AND. environ%get_verbosity() > 1) WRITE (stdout, 1000)
!
CALL environ%calc%potential(update_venviron)
!
!--------------------------------------------------------------------------------
!
1000 FORMAT(/, 5X, "add environment contribution to local potential")
!
!--------------------------------------------------------------------------------
END SUBROUTINE calc_environ_potential
!------------------------------------------------------------------------------------
!
!------------------------------------------------------------------------------------
END MODULE environ_cp_module
!----------------------------------------------------------------------------------------
#endif

View File

@ -0,0 +1,382 @@
#if defined (__ENVIRON)
!----------------------------------------------------------------------------------------
!>
!!
!----------------------------------------------------------------------------------------
MODULE environ_base_module
!------------------------------------------------------------------------------------
!
USE environ_api, ONLY: environ_interface
!
USE kinds, ONLY: DP
USE io_global, ONLY: ionode, ionode_id, stdout
!
USE mp_images, ONLY: intra_image_comm
USE mp_bands, ONLY: intra_bgrp_comm
!
USE control_flags, ONLY: conv_elec, iverbosity
!
USE fft_base, ONLY: dfftp
!
USE ions_base, ONLY: nat, nsp, ityp, atm, zv
!
!------------------------------------------------------------------------------------
!
IMPLICIT NONE
!
PRIVATE
!
PUBLIC :: read_environ_input
!
PUBLIC :: init_environ_setup, init_environ_base
!
PUBLIC :: clean_environ, check_environ_compatibility
!
PUBLIC :: update_environ_ions, update_environ_cell
!
PUBLIC :: calc_environ_energy, calc_environ_force
!
PUBLIC :: print_environ_summary, print_environ_energies, print_environ_clocks
!
!------------------------------------------------------------------------------------
!
TYPE(environ_interface), PUBLIC :: environ
!
!------------------------------------------------------------------------------------
CONTAINS
!------------------------------------------------------------------------------------
!------------------------------------------------------------------------------------
!
! ADMIN ROUTINES
!
!------------------------------------------------------------------------------------
!------------------------------------------------------------------------------------
!>
!!
!------------------------------------------------------------------------------------
SUBROUTINE read_environ_input()
!--------------------------------------------------------------------------------
!
CALL environ%init_interface()
!
CALL environ%init_io(ionode, ionode_id, intra_image_comm, stdout, ionode)
!
CALL environ%read_input()
!
!--------------------------------------------------------------------------------
END SUBROUTINE read_environ_input
!------------------------------------------------------------------------------------
!>
!!
!------------------------------------------------------------------------------------
SUBROUTINE init_environ_setup(prog, do_comp_mt)
!--------------------------------------------------------------------------------
!
IMPLICIT NONE
!
CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: prog
LOGICAL, OPTIONAL, INTENT(IN) :: do_comp_mt
!
CHARACTER(LEN=80) :: sub_name = 'init_environ_setup'
!
!--------------------------------------------------------------------------------
!
CALL environ%setup%init(do_comp_mt)
!
IF (PRESENT(prog)) THEN
IF (prog == 'TD') CALL environ%setup%set_tddfpt(.TRUE.)
END IF
!
!--------------------------------------------------------------------------------
END SUBROUTINE init_environ_setup
!------------------------------------------------------------------------------------
!>
!!
!------------------------------------------------------------------------------------
SUBROUTINE init_environ_base(at, gcutm)
!--------------------------------------------------------------------------------
!
IMPLICIT NONE
!
REAL(DP), INTENT(IN) :: at(3, 3)
REAL(DP), INTENT(IN) :: gcutm
!
INTEGER :: nr(3)
!
CHARACTER(LEN=80) :: sub_name = 'init_environ_base'
!
!--------------------------------------------------------------------------------
!
nr(1) = dfftp%nr1
nr(2) = dfftp%nr2
nr(3) = dfftp%nr3
!
CALL environ%setup%init_cell(gcutm, intra_bgrp_comm, at, nr)
!
CALL environ%setup%init_cores(gcutm)
!
CALL environ%main%init(1, nat, nsp, atm, ityp, zv)
!
!--------------------------------------------------------------------------------
END SUBROUTINE init_environ_base
!------------------------------------------------------------------------------------
!>
!!
!------------------------------------------------------------------------------------
SUBROUTINE clean_environ(prog, lflag)
!--------------------------------------------------------------------------------
!
IMPLICIT NONE
!
CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: prog
LOGICAL, OPTIONAL, INTENT(IN) :: lflag
!
CHARACTER(LEN=80) :: sub_name = 'clean_environ'
!
!--------------------------------------------------------------------------------
!
IF (PRESENT(prog)) THEN
!
SELECT CASE (prog)
!
CASE ('PW')
!
!------------------------------------------------------------------------
! When called by PW, but inside a TD calculation, do not clean Environ
! variables - they have already been cleaned by TD. The lflag input is
! used to fully clean the variable or to only clean variables initialized
! during the PW run and not the ones initialized while processing the
! input. This allows NEB simulations
!
IF (.NOT. environ%setup%is_tddfpt()) CALL environ%destroy()
!
CASE ('TD')
!
!------------------------------------------------------------------------
! When called by TD, use the flag input variable to specify whether
! to clean the PW variables or the TD variables. In both cases, the
! variables are fully cleaned (no NEB with TD)
!
IF (PRESENT(lflag)) THEN
!
IF (.NOT. lflag) THEN
CALL environ%destroy(1)
ELSE
CALL environ%destroy(2)
END IF
!
ELSE
CALL errore(sub_name, "Missing TDDFPT clean flag", 1)
END IF
!
CASE DEFAULT
CALL errore(sub_name, "Unexpected calling program", 1)
!
END SELECT
!
ELSE
CALL environ%destroy()
END IF
!
!--------------------------------------------------------------------------------
END SUBROUTINE clean_environ
!------------------------------------------------------------------------------------
!>
!!
!------------------------------------------------------------------------------------
SUBROUTINE check_environ_compatibility(routine)
!--------------------------------------------------------------------------------
!
IMPLICIT NONE
!
CHARACTER(LEN=*), INTENT(IN) :: routine
!
CHARACTER(LEN=80) :: sub_name = 'check_environ_compatibility'
!
!--------------------------------------------------------------------------------
!
CALL errore(routine, "Calculation not compatible with Environ embedding", 1)
!
!--------------------------------------------------------------------------------
END SUBROUTINE check_environ_compatibility
!------------------------------------------------------------------------------------
!------------------------------------------------------------------------------------
!
! UPDATE ROUTINES
!
!------------------------------------------------------------------------------------
!------------------------------------------------------------------------------------
!>
!!
!------------------------------------------------------------------------------------
SUBROUTINE update_environ_ions(tau)
!--------------------------------------------------------------------------------
!
IMPLICIT NONE
!
REAL(DP), OPTIONAL, INTENT(IN) :: tau(3, nat)
!
CHARACTER(LEN=80) :: sub_name = 'update_environ_ions'
!
!--------------------------------------------------------------------------------
!
CALL environ%main%update_ions(nat, tau)
!
!--------------------------------------------------------------------------------
END SUBROUTINE update_environ_ions
!------------------------------------------------------------------------------------
!>
!!
!------------------------------------------------------------------------------------
SUBROUTINE update_environ_cell(at)
!--------------------------------------------------------------------------------
!
IMPLICIT NONE
!
REAL(DP), INTENT(IN) :: at(3, 3)
!
CHARACTER(LEN=80) :: sub_name = 'update_environ_cell'
!
!--------------------------------------------------------------------------------
!
CALL environ%update_cell(at)
!
!--------------------------------------------------------------------------------
END SUBROUTINE update_environ_cell
!------------------------------------------------------------------------------------
!------------------------------------------------------------------------------------
!
! COMPUTATION ROUTINES
!
!------------------------------------------------------------------------------------
!------------------------------------------------------------------------------------
!>
!! Compute environ contributions to total energy
!! Note: plugin_etot is set to 0.0_dp right before this routine is called
!!
!------------------------------------------------------------------------------------
SUBROUTINE calc_environ_energy(plugin_etot, de_flag)
!--------------------------------------------------------------------------------
!
IMPLICIT NONE
!
LOGICAL, OPTIONAL, INTENT(IN) :: de_flag
!
REAL(DP), INTENT(INOUT) :: plugin_etot
!
CHARACTER(LEN=80) :: sub_name = 'calc_environ_energy'
!
!--------------------------------------------------------------------------------
!
IF (PRESENT(de_flag)) THEN
IF (de_flag) CALL environ%calc%denergy(plugin_etot)
END IF
!
CALL environ%calc%energy(plugin_etot)
!
!--------------------------------------------------------------------------------
END SUBROUTINE calc_environ_energy
!------------------------------------------------------------------------------------
!>
!! Compute environ contributions to total energy
!! Note: plugin_etot is set to 0.0_dp right before this routine is called
!!
!------------------------------------------------------------------------------------
SUBROUTINE calc_environ_force(force)
!--------------------------------------------------------------------------------
!
IMPLICIT NONE
!
REAL(DP), INTENT(OUT) :: force(3, nat)
!
INTEGER :: i, j
!
CHARACTER(LEN=80) :: sub_name = 'calc_environ_force'
!
!--------------------------------------------------------------------------------
!
force = 0.D0
!
CALL environ%calc%force(nat, force)
!
IF (iverbosity > 0) THEN
WRITE (stdout, 1001)
!
DO j = 1, nat
WRITE (stdout, 1002) j, ityp(j), (force(i, j), i=1, 3)
END DO
!
WRITE (stdout, *)
END IF
!
!--------------------------------------------------------------------------------
!
1001 FORMAT(5X, "The dielectric solvent contribution to forces")
1002 FORMAT(5X, "atom ", I4, " type ", I2, " force = ", 3F14.8)
!
!--------------------------------------------------------------------------------
END SUBROUTINE calc_environ_force
!------------------------------------------------------------------------------------
!------------------------------------------------------------------------------------
!
! OUTPUT ROUTINES
!
!------------------------------------------------------------------------------------
!------------------------------------------------------------------------------------
!>
!!
!------------------------------------------------------------------------------------
SUBROUTINE print_environ_summary()
!--------------------------------------------------------------------------------
!
CALL environ%setup%print_summary(stdout)
!
!--------------------------------------------------------------------------------
END SUBROUTINE print_environ_summary
!------------------------------------------------------------------------------------
!>
!!
!------------------------------------------------------------------------------------
SUBROUTINE print_environ_energies(prog)
!--------------------------------------------------------------------------------
!
IMPLICIT NONE
!
CHARACTER(LEN=*), INTENT(IN) :: prog
!
CHARACTER(LEN=80) :: sub_name = 'print_environ_energies'
!
!--------------------------------------------------------------------------------
!
CALL environ%main%print_energies(prog)
!
IF (prog == 'PW' .AND. conv_elec) CALL environ%setup%print_potential_warning()
!
!--------------------------------------------------------------------------------
END SUBROUTINE print_environ_energies
!------------------------------------------------------------------------------------
!>
!!
!------------------------------------------------------------------------------------
SUBROUTINE print_environ_clocks()
!--------------------------------------------------------------------------------
!
CALL environ%setup%print_clocks()
!
!--------------------------------------------------------------------------------
END SUBROUTINE print_environ_clocks
!------------------------------------------------------------------------------------
!
!------------------------------------------------------------------------------------
END MODULE environ_base_module
!----------------------------------------------------------------------------------------
#else
!----------------------------------------------------------------------------------------
!>
!! Stand-in module for Environ's API
!!
!----------------------------------------------------------------------------------------
MODULE environ_api
END MODULE environ_api
!----------------------------------------------------------------------------------------
#endif

View File

@ -0,0 +1,125 @@
#if defined (__ENVIRON)
!----------------------------------------------------------------------------------------
!>
!!
!----------------------------------------------------------------------------------------
MODULE environ_pw_module
!------------------------------------------------------------------------------------
!
USE environ_base_module, ONLY: environ
!
USE kinds, ONLY: DP
USE global_version, ONLY: version_number
USE io_global, ONLY: stdout
!
USE control_flags, ONLY: lscf
!
USE fft_base, ONLY: dfftp
!
USE scf, ONLY: scf_type
USE klist, ONLY: nelec
USE lsda_mod, ONLY: nspin
!
!------------------------------------------------------------------------------------
!
IMPLICIT NONE
!
PRIVATE
!
PUBLIC :: update_environ_potential, calc_environ_potential
!
!------------------------------------------------------------------------------------
CONTAINS
!------------------------------------------------------------------------------------
!>
!!
!------------------------------------------------------------------------------------
SUBROUTINE update_environ_potential(vltot)
!--------------------------------------------------------------------------------
!
IMPLICIT NONE
!
REAL(DP), INTENT(IN) :: vltot(dfftp%nnr)
!
CHARACTER(LEN=80) :: sub_name = 'update_environ_potential'
!
!--------------------------------------------------------------------------------
!
CALL environ%main%update_potential(dfftp%nnr, vltot)
!
!--------------------------------------------------------------------------------
END SUBROUTINE update_environ_potential
!------------------------------------------------------------------------------------
!>
!!
!------------------------------------------------------------------------------------
SUBROUTINE calc_environ_potential(rhoin, converged, dr2, vltot)
!--------------------------------------------------------------------------------
!
IMPLICIT NONE
!
TYPE(scf_type), INTENT(IN) :: rhoin
LOGICAL, INTENT(IN) :: converged
REAL(DP), INTENT(IN) :: dr2
!
REAL(DP), INTENT(INOUT) :: vltot(dfftp%nnr)
!
LOGICAL :: update_venviron = .FALSE.
INTEGER :: local_verbose = 0
!
REAL(DP) :: rhoaux(dfftp%nnr)
!
CHARACTER(LEN=80) :: sub_name = 'calc_environ_potential'
!
!--------------------------------------------------------------------------------
! Reduce output at each scf iteration
!
IF (.NOT. lscf .OR. converged) local_verbose = 1
!
!--------------------------------------------------------------------------------
! update electrons-related quantities in environ
!
rhoaux = rhoin%of_r(:, 1)
!
IF (version_number == '6.3') THEN
IF (nspin == 2) rhoaux = rhoaux + rhoin%of_r(:, 2)
END IF
!
CALL environ%main%update_electrons(dfftp%nnr, rhoaux, nelec)
!
!--------------------------------------------------------------------------------
! Environ contribution to the local potential
!
IF (dr2 > 0.0_DP) THEN
update_venviron = .NOT. converged .AND. dr2 < environ%setup%get_threshold()
ELSE
update_venviron = environ%setup%is_restart() .OR. environ%setup%is_tddfpt()
!
!----------------------------------------------------------------------------
! For subsequent steps of optimization or dynamics, compute Environ
! contribution during initialization
!
CALL environ%setup%set_restart(.TRUE.)
!
END IF
!
IF (update_venviron) WRITE (stdout, 1000)
!
CALL environ%calc%potential(update_venviron, local_verbose)
!
vltot = environ%main%get_vzero(dfftp%nnr) + environ%main%get_dvtot(dfftp%nnr)
!
IF (.NOT. lscf .OR. converged) CALL environ%main%print_potential_shift()
!
!--------------------------------------------------------------------------------
!
1000 FORMAT(/, 5X, "add environment contribution to local potential")
!
!--------------------------------------------------------------------------------
END SUBROUTINE calc_environ_potential
!------------------------------------------------------------------------------------
!
!------------------------------------------------------------------------------------
END MODULE environ_pw_module
!----------------------------------------------------------------------------------------
#endif

View File

@ -0,0 +1,65 @@
#if defined (__ENVIRON)
!----------------------------------------------------------------------------------------
!>
!!
!----------------------------------------------------------------------------------------
MODULE environ_td_module
!------------------------------------------------------------------------------------
!
USE environ_base_module, ONLY: environ
!
USE kinds, ONLY: DP
USE io_global, ONLY: stdout
!
USE fft_base, ONLY: dfftp
!
USE lsda_mod, ONLY: nspin
USE lr_variables, ONLY: davidson
!
!------------------------------------------------------------------------------------
!
IMPLICIT NONE
!
PRIVATE
!
PUBLIC :: calc_environ_dpotential
!
!------------------------------------------------------------------------------------
CONTAINS
!------------------------------------------------------------------------------------
!>
!!
!------------------------------------------------------------------------------------
SUBROUTINE calc_environ_dpotential(drho, dv)
!--------------------------------------------------------------------------------
!
IMPLICIT NONE
!
REAL(DP), INTENT(IN) :: drho(dfftp%nnr, nspin)
!
REAL(DP), INTENT(INOUT) :: dv(dfftp%nnr, nspin)
!
!--------------------------------------------------------------------------------
!
IF (.NOT. davidson) WRITE (stdout, 1000)
!
IF (environ%setup%optical_permittivity == 1.D0) WRITE (stdout, 1002)
!
CALL environ%main%update_response(dfftp%nnr, drho(:, 1))
!
CALL environ%calc%dpotential(dfftp%nnr, dv(:, 1))
!
!--------------------------------------------------------------------------------
!
1000 FORMAT(5X, "Calculate Environ contribution to response potential")
!
1002 FORMAT("Warning: permittivity is set to 1.0 - no Environ contribution")
!
!--------------------------------------------------------------------------------
END SUBROUTINE calc_environ_dpotential
!------------------------------------------------------------------------------------
!
!------------------------------------------------------------------------------------
END MODULE environ_td_module
!----------------------------------------------------------------------------------------
#endif