Evaluation of the dispersion energy expression
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(mzero_damping_param), | intent(in) | :: | self |
Damping parameters |
||
class(structure_type), | intent(in) | :: | mol |
Molecular structure data |
||
real(kind=wp), | intent(in) | :: | trans(:,:) |
Lattice points |
||
real(kind=wp), | intent(in) | :: | cutoff |
Real space cutoff |
||
real(kind=wp), | intent(in) | :: | rvdw(:,:) |
Van-der-Waals radii for damping function |
||
real(kind=wp), | intent(in) | :: | r4r2(:) |
Expectation values for C8 extrapolation |
||
real(kind=wp), | intent(in) | :: | c6(:,:) |
C6 coefficients for all atom pairs. |
||
real(kind=wp), | intent(inout) | :: | energy(:) |
Dispersion energy |
subroutine get_dispersion_energy(self, mol, trans, cutoff, rvdw, r4r2, c6, energy) !> Damping parameters class(mzero_damping_param), intent(in) :: self !> Molecular structure data class(structure_type), intent(in) :: mol !> Lattice points real(wp), intent(in) :: trans(:, :) !> Real space cutoff real(wp), intent(in) :: cutoff !> Van-der-Waals radii for damping function real(wp), intent(in) :: rvdw(:, :) !> Expectation values for C8 extrapolation real(wp), intent(in) :: r4r2(:) !> C6 coefficients for all atom pairs. real(wp), intent(in) :: c6(:, :) !> Dispersion energy real(wp), intent(inout) :: energy(:) integer :: iat, jat, izp, jzp, jtr real(wp) :: vec(3), r2, r1, r6, r8, t6, t8, f6, f8, alp6, alp8 real(wp) :: edisp, cutoff2, r0ij, rrij, c6ij, dE cutoff2 = cutoff*cutoff alp6 = self%alp alp8 = self%alp + 2.0_wp !$omp parallel do schedule(runtime) default(none) reduction(+:energy) & !$omp shared(mol, self, c6, trans, cutoff2, alp6, alp8, rvdw, r4r2) & !$omp private(iat, jat, izp, jzp, jtr, vec, r2, r1, r6, r8, t6, t8, f6, & !$omp& f8, edisp, r0ij, rrij, c6ij, dE) do iat = 1, mol%nat izp = mol%id(iat) do jat = 1, iat jzp = mol%id(jat) rrij = 3*r4r2(izp)*r4r2(jzp) r0ij = rvdw(jzp, izp) c6ij = c6(jat, iat) do jtr = 1, size(trans, 2) vec(:) = mol%xyz(:, iat) - (mol%xyz(:, jat) + trans(:, jtr)) r2 = vec(1)*vec(1) + vec(2)*vec(2) + vec(3)*vec(3) if (r2 > cutoff2 .or. r2 < epsilon(1.0_wp)) cycle r1 = sqrt(r2) r6 = r2*r2*r2 r8 = r6*r2 t6 = (r1/(self%rs6*r0ij)+self%bet*r0ij)**(-alp6) t8 = (r1/(self%rs8*r0ij)+self%bet*r0ij)**(-alp8) f6 = 1.0_wp / (1.0_wp + 6.0_wp*t6) f8 = 1.0_wp / (1.0_wp + 6.0_wp*t8) edisp = self%s6 * f6 / r6 + self%s8 * rrij * f8 / r8 dE = -c6ij*edisp * 0.5_wp energy(iat) = energy(iat) + dE if (iat /= jat) then energy(jat) = energy(jat) + dE end if end do end do end do end subroutine get_dispersion_energy