(git:1f9fd2c)
Loading...
Searching...
No Matches
qs_dispersion_d3.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Calculation of D3 dispersion
10!> \author JGH
11! **************************************************************************************************
13
19 USE cell_types, ONLY: cell_type,&
20 get_cell,&
21 pbc,&
23 USE cp_files, ONLY: close_file,&
27 USE kinds, ONLY: dp
28 USE mathconstants, ONLY: twopi
32 USE physcon, ONLY: kcalmol
37 USE qs_dispersion_types, ONLY: dftd3_pp,&
44 USE qs_kind_types, ONLY: get_qs_kind,&
53 USE virial_types, ONLY: virial_type
54#include "./base/base_uses.f90"
55
56 IMPLICIT NONE
57
58 PRIVATE
59
60 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_dispersion_d3'
61
63
64! **************************************************************************************************
65
66CONTAINS
67
68! **************************************************************************************************
69!> \brief ...
70!> \param qs_env ...
71!> \param dispersion_env ...
72!> \param evdw ...
73!> \param calculate_forces ...
74!> \param unit_nr ...
75!> \param atevdw ...
76! **************************************************************************************************
77 SUBROUTINE calculate_dispersion_d3_pairpot(qs_env, dispersion_env, evdw, calculate_forces, &
78 unit_nr, atevdw)
79
80 TYPE(qs_environment_type), POINTER :: qs_env
81 TYPE(qs_dispersion_type), POINTER :: dispersion_env
82 REAL(kind=dp), INTENT(OUT) :: evdw
83 LOGICAL, INTENT(IN) :: calculate_forces
84 INTEGER, INTENT(IN) :: unit_nr
85 REAL(kind=dp), DIMENSION(:), OPTIONAL :: atevdw
86
87 CHARACTER(LEN=*), PARAMETER :: routinen = 'calculate_dispersion_d3_pairpot'
88
89 INTEGER :: atom_a, atom_b, atom_c, atom_d, handle, hashb, hashc, i, ia, iat, iatom, icx, &
90 icy, icz, idmp, ikind, ilist, imol, jatom, jkind, katom, kkind, kstart, latom, lkind, &
91 max_elem, maxc, mepos, na, natom, nb, nc, nkind, num_pe, za, zb, zc
92 INTEGER, ALLOCATABLE, DIMENSION(:) :: atom_of_kind, atomnumber, kind_of
93 INTEGER, DIMENSION(3) :: cell_b, cell_c, ncell, periodic
94 INTEGER, DIMENSION(:), POINTER :: atom_list
95 LOGICAL :: atenergy, atex, debugall, domol, exclude_pair, floating_a, floating_b, &
96 floating_c, ghost_a, ghost_b, ghost_c, is000, use_virial
97 LOGICAL, ALLOCATABLE, DIMENSION(:) :: dodisp, exclude
98 REAL(kind=dp) :: a1, a2, alp6, alp8, ang, c6, c8, c9, cc6ab, cc6bc, cc6ca, cnum, dc6a, dc6b, &
99 dc8a, dc8b, dcc6aba, dcc6abb, dcc6bcb, dcc6bcc, dcc6caa, dcc6cac, de6, de8, de91, de921, &
100 de922, dea, dfdab6, dfdab8, dfdabc, dr, drk, e6, e6tot, e8, e8tot, e9, e9tot, elrc6, &
101 elrc8, elrc9, eps_cn, esrb, f0ab, fac, fac0, fdab6, fdab8, fdabc, gsrb, kgc8, nab, nabc, &
102 r0, r0ab, r2ab, r2abc, r2bc, r2ca, r6, r8, rabc, rc2, rcc, rcut, rs6, rs8, s1, s2, s3, &
103 s6, s8, s8i, s9, srbe, ssrb, t1srb, t2srb
104 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: atom2mol, c6d2, cnkind, cnumbers, &
105 cnumfix, radd2
106 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: rcpbc
107 REAL(kind=dp), DIMENSION(3) :: fdij, fdik, ra, rab, rb, rb0, rbc, rc, &
108 rc0, rca, rij, rik, sab_max
109 REAL(kind=dp), DIMENSION(3, 3) :: pv_virial_thread
110 REAL(kind=dp), DIMENSION(:), POINTER :: atener
111 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
112 TYPE(atprop_type), POINTER :: atprop
113 TYPE(cell_type), POINTER :: cell
114 TYPE(dcnum_type), ALLOCATABLE, DIMENSION(:) :: dcnum
115 TYPE(molecule_type), DIMENSION(:), POINTER :: molecule_set
116 TYPE(mp_para_env_type), POINTER :: para_env
118 DIMENSION(:), POINTER :: nl_iterator
119 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
120 POINTER :: sab_vdw
121 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
122 TYPE(qs_atom_dispersion_type), POINTER :: disp_a, disp_b, disp_c
123 TYPE(qs_force_type), DIMENSION(:), POINTER :: force
124 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
125 TYPE(virial_type), POINTER :: virial
126
127 CALL timeset(routinen, handle)
128
129 evdw = 0._dp
130
131 NULLIFY (atomic_kind_set, qs_kind_set, sab_vdw)
132
133 CALL get_qs_env(qs_env=qs_env, nkind=nkind, natom=natom, atomic_kind_set=atomic_kind_set, &
134 qs_kind_set=qs_kind_set, cell=cell, virial=virial, para_env=para_env, atprop=atprop)
135
136 debugall = dispersion_env%verbose
137
138 ! atomic energy and stress arrays
139 atenergy = atprop%energy
140 IF (atenergy) THEN
141 CALL atprop_array_init(atprop%atevdw, natom)
142 atener => atprop%atevdw
143 END IF
144 ! external atomic energy
145 atex = .false.
146 IF (PRESENT(atevdw)) THEN
147 atex = .true.
148 END IF
149
150 NULLIFY (particle_set)
151 CALL get_qs_env(qs_env=qs_env, particle_set=particle_set)
152 natom = SIZE(particle_set)
153
154 NULLIFY (force)
155 CALL get_qs_env(qs_env=qs_env, force=force)
156 CALL get_atomic_kind_set(atomic_kind_set, atom_of_kind=atom_of_kind, kind_of=kind_of)
157 use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
158 pv_virial_thread(:, :) = 0._dp
159
160 ALLOCATE (dodisp(nkind), exclude(nkind), atomnumber(nkind), c6d2(nkind), radd2(nkind))
161 DO ikind = 1, nkind
162 CALL get_atomic_kind(atomic_kind_set(ikind), z=za)
163 CALL get_qs_kind(qs_kind_set(ikind), dispersion=disp_a, ghost=ghost_a, floating=floating_a)
164 dodisp(ikind) = disp_a%defined
165 exclude(ikind) = ghost_a .OR. floating_a
166 atomnumber(ikind) = za
167 c6d2(ikind) = disp_a%c6
168 radd2(ikind) = disp_a%vdw_radii
169 END DO
170
171 ALLOCATE (rcpbc(3, natom))
172 DO iatom = 1, natom
173 rcpbc(:, iatom) = pbc(particle_set(iatom)%r(:), cell)
174 END DO
175
176 rcut = 2._dp*dispersion_env%rc_disp
177 rc2 = rcut*rcut
178
179 maxc = SIZE(dispersion_env%c6ab, 3)
180 max_elem = SIZE(dispersion_env%c6ab, 1)
181 alp6 = dispersion_env%alp
182 alp8 = alp6 + 2._dp
183 s6 = dispersion_env%s6
184 s8 = dispersion_env%s8
185 s9 = dispersion_env%s6
186 rs6 = dispersion_env%sr6
187 rs8 = 1._dp
188 a1 = dispersion_env%a1
189 a2 = dispersion_env%a2
190 eps_cn = dispersion_env%eps_cn
191 e6tot = 0._dp
192 e8tot = 0._dp
193 e9tot = 0._dp
194 esrb = 0._dp
195 domol = dispersion_env%domol
196 ! molecule correction
197 kgc8 = dispersion_env%kgc8
198 IF (domol) THEN
199 CALL get_qs_env(qs_env=qs_env, molecule_set=molecule_set)
200 ALLOCATE (atom2mol(natom))
201 DO imol = 1, SIZE(molecule_set)
202 DO iat = molecule_set(imol)%first_atom, molecule_set(imol)%last_atom
203 atom2mol(iat) = imol
204 END DO
205 END DO
206 END IF
207 ! damping type
208 idmp = 0
209 IF (dispersion_env%pp_type == vdw_pairpot_dftd3) THEN
210 idmp = 1
211 ELSE IF (dispersion_env%pp_type == vdw_pairpot_dftd3bj) THEN
212 idmp = 2
213 END IF
214 ! SRB parameters
215 ssrb = dispersion_env%srb_params(1)
216 gsrb = dispersion_env%srb_params(2)
217 t1srb = dispersion_env%srb_params(3)
218 t2srb = dispersion_env%srb_params(4)
219
220 IF (unit_nr > 0) THEN
221 WRITE (unit_nr, *) " Scaling parameter (s6) ", s6
222 WRITE (unit_nr, *) " Scaling parameter (s8) ", s8
223 IF (dispersion_env%pp_type == vdw_pairpot_dftd3) THEN
224 WRITE (unit_nr, *) " Zero Damping parameter (sr6)", rs6
225 WRITE (unit_nr, *) " Zero Damping parameter (sr8)", rs8
226 ELSE IF (dispersion_env%pp_type == vdw_pairpot_dftd3bj) THEN
227 WRITE (unit_nr, *) " BJ Damping parameter (a1) ", a1
228 WRITE (unit_nr, *) " BJ Damping parameter (a2) ", a2
229 END IF
230 WRITE (unit_nr, *) " Cutoff coordination numbers", eps_cn
231 IF (dispersion_env%lrc) THEN
232 WRITE (unit_nr, *) " Apply a long range correction"
233 END IF
234 IF (dispersion_env%srb) THEN
235 WRITE (unit_nr, *) " Apply a short range bond correction"
236 WRITE (unit_nr, *) " SRB parameters (s,g,t1,t2) ", ssrb, gsrb, t1srb, t2srb
237 END IF
238 IF (domol) THEN
239 WRITE (unit_nr, *) " Inter-molecule scaling parameter (s8) ", kgc8
240 END IF
241 END IF
242 ! Calculate coordination numbers
243 NULLIFY (particle_set)
244 CALL get_qs_env(qs_env=qs_env, particle_set=particle_set)
245 natom = SIZE(particle_set)
246 ALLOCATE (cnumbers(natom))
247 cnumbers = 0._dp
248
249 IF (calculate_forces .OR. debugall) THEN
250 ALLOCATE (dcnum(natom))
251 dcnum(:)%neighbors = 0
252 DO iatom = 1, natom
253 ALLOCATE (dcnum(iatom)%nlist(10), dcnum(iatom)%dvals(10), dcnum(iatom)%rik(3, 10))
254 END DO
255 ELSE
256 ALLOCATE (dcnum(1))
257 END IF
258
259 CALL d3_cnumber(qs_env, dispersion_env, cnumbers, dcnum, exclude, atomnumber, &
260 calculate_forces, 1)
261
262 CALL para_env%sum(cnumbers)
263
264 ! for parallel runs we have to update dcnum on all processors
265 IF (calculate_forces .OR. debugall) THEN
266 CALL dcnum_distribute(dcnum, para_env)
267 IF (unit_nr > 0 .AND. SIZE(dcnum) > 0) THEN
268 WRITE (unit_nr, *)
269 WRITE (unit_nr, *) " ATOM Coordination Neighbors"
270 DO i = 1, natom
271 WRITE (unit_nr, "(I6,F20.10,I12)") i, cnumbers(i), dcnum(i)%neighbors
272 END DO
273 WRITE (unit_nr, *)
274 END IF
275 END IF
276
277 nab = 0._dp
278 nabc = 0._dp
279 IF (dispersion_env%doabc) THEN
280 rcc = 2._dp*dispersion_env%rc_disp
281 CALL get_cell(cell=cell, periodic=periodic)
282 sab_max(1) = rcc/plane_distance(1, 0, 0, cell)
283 sab_max(2) = rcc/plane_distance(0, 1, 0, cell)
284 sab_max(3) = rcc/plane_distance(0, 0, 1, cell)
285 ncell(:) = (int(sab_max(:)) + 1)*periodic(:)
286 IF (unit_nr > 0) THEN
287 WRITE (unit_nr, *) " Calculate C9 Terms"
288 WRITE (unit_nr, "(A,T20,I3,A,I3)") " Search in cells ", -ncell(1), ":", ncell(1)
289 WRITE (unit_nr, "(T20,I3,A,I3)") - ncell(2), ":", ncell(2)
290 WRITE (unit_nr, "(T20,I3,A,I3)") - ncell(3), ":", ncell(3)
291 WRITE (unit_nr, *)
292 END IF
293 IF (dispersion_env%c9cnst) THEN
294 IF (unit_nr > 0) WRITE (unit_nr, *) " Use reference coordination numbers for C9 term"
295 ALLOCATE (cnumfix(natom))
296 cnumfix = 0._dp
297 ! first use the default values
298 DO iatom = 1, natom
299 ikind = kind_of(iatom)
300 CALL get_atomic_kind(atomic_kind_set(ikind), z=za)
301 cnumfix(iatom) = dispersion_env%cn(za)
302 END DO
303 ! now check for changes from default
304 IF (ASSOCIATED(dispersion_env%cnkind)) THEN
305 DO i = 1, SIZE(dispersion_env%cnkind)
306 ikind = dispersion_env%cnkind(i)%kind
307 cnum = dispersion_env%cnkind(i)%cnum
308 cpassert(ikind <= nkind)
309 cpassert(ikind > 0)
310 CALL get_atomic_kind(atomic_kind_set(ikind), natom=na, atom_list=atom_list)
311 DO ia = 1, na
312 iatom = atom_list(ia)
313 cnumfix(iatom) = cnum
314 END DO
315 END DO
316 END IF
317 IF (ASSOCIATED(dispersion_env%cnlist)) THEN
318 DO i = 1, SIZE(dispersion_env%cnlist)
319 DO ilist = 1, dispersion_env%cnlist(i)%natom
320 iatom = dispersion_env%cnlist(i)%atom(ilist)
321 cnumfix(iatom) = dispersion_env%cnlist(i)%cnum
322 END DO
323 END DO
324 END IF
325 IF (unit_nr > 0) THEN
326 DO i = 1, natom
327 IF (abs(cnumbers(i) - cnumfix(i)) > 0.5_dp) THEN
328 WRITE (unit_nr, "(A,T20,A,I6,T41,2F10.3)") " Difference in CN ", "Atom:", &
329 i, cnumbers(i), cnumfix(i)
330 END IF
331 END DO
332 WRITE (unit_nr, *)
333 END IF
334 END IF
335 END IF
336
337 sab_vdw => dispersion_env%sab_vdw
338
339 num_pe = 1
340 CALL neighbor_list_iterator_create(nl_iterator, sab_vdw, nthread=num_pe)
341
342 mepos = 0
343 DO WHILE (neighbor_list_iterate(nl_iterator, mepos=mepos) == 0)
344 CALL get_iterator_info(nl_iterator, mepos=mepos, ikind=ikind, jkind=jkind, iatom=iatom, jatom=jatom, r=rij)
345
346 IF (exclude(ikind) .OR. exclude(jkind)) cycle
347
348 IF (.NOT. (dodisp(ikind) .AND. dodisp(jkind))) cycle
349
350 za = atomnumber(ikind)
351 zb = atomnumber(jkind)
352 ! vdW potential
353 dr = sqrt(sum(rij(:)**2))
354 IF (dr <= rcut) THEN
355 nab = nab + 1._dp
356 fac = 1._dp
357 IF (iatom == jatom) fac = 0.5_dp
358 IF (disp_a%type == dftd3_pp .AND. dr > 0.001_dp) THEN
359 IF (dispersion_env%nd3_exclude_pair > 0) THEN
360 CALL exclude_d3_kind_pair(dispersion_env%d3_exclude_pair, ikind, jkind, &
361 exclude=exclude_pair)
362 IF (exclude_pair) cycle
363 END IF
364 ! C6 coefficient
365 CALL getc6(maxc, max_elem, dispersion_env%c6ab, dispersion_env%maxci, za, zb, &
366 cnumbers(iatom), cnumbers(jatom), dispersion_env%k3, c6, dc6a, dc6b)
367 c8 = 3.0d0*c6*dispersion_env%r2r4(za)*dispersion_env%r2r4(zb)
368 dc8a = 3.0d0*dc6a*dispersion_env%r2r4(za)*dispersion_env%r2r4(zb)
369 dc8b = 3.0d0*dc6b*dispersion_env%r2r4(za)*dispersion_env%r2r4(zb)
370 r6 = dr**6
371 r8 = r6*dr*dr
372 s8i = s8
373 IF (domol) THEN
374 IF (atom2mol(iatom) /= atom2mol(jatom)) THEN
375 s8i = kgc8
376 END IF
377 END IF
378 ! damping
379 IF (idmp == 1) THEN
380 ! zero
381 CALL damping_d3(dr, dispersion_env%r0ab(za, zb), rs6, alp6, rcut, fdab6, dfdab6)
382 CALL damping_d3(dr, dispersion_env%r0ab(za, zb), rs8, alp8, rcut, fdab8, dfdab8)
383 e6 = s6*fac*c6*fdab6/r6
384 e8 = s8i*fac*c8*fdab8/r8
385 ELSE IF (idmp == 2) THEN
386 ! BJ
387 r0ab = sqrt(3.0d0*dispersion_env%r2r4(za)*dispersion_env%r2r4(zb))
388 f0ab = a1*r0ab + a2
389 fdab6 = 1.0_dp/(r6 + f0ab**6)
390 fdab8 = 1.0_dp/(r8 + f0ab**8)
391 e6 = s6*fac*c6*fdab6
392 e8 = s8i*fac*c8*fdab8
393 ELSE
394 cpabort("Unknown DFT-D3 damping function:")
395 END IF
396 IF (dispersion_env%srb .AND. dr < 30.0d0) THEN
397 srbe = ssrb*(real((za*zb), kind=dp))**t1srb*exp(-gsrb*dr*dispersion_env%r0ab(za, zb)**t2srb)
398 esrb = esrb + srbe
399 evdw = evdw - srbe
400 ELSE
401 srbe = 0.0_dp
402 END IF
403 evdw = evdw - e6 - e8
404 e6tot = e6tot - e6
405 e8tot = e8tot - e8
406 IF (atenergy) THEN
407 atener(iatom) = atener(iatom) - 0.5_dp*(e6 + e8 + srbe)
408 atener(jatom) = atener(jatom) - 0.5_dp*(e6 + e8 + srbe)
409 END IF
410 IF (atex) THEN
411 atevdw(iatom) = atevdw(iatom) - 0.5_dp*(e6 + e8 + srbe)
412 atevdw(jatom) = atevdw(jatom) - 0.5_dp*(e6 + e8 + srbe)
413 END IF
414 IF (calculate_forces) THEN
415 ! damping
416 IF (idmp == 1) THEN
417 ! zero
418 de6 = -s6*c6/r6*(dfdab6 - 6._dp*fdab6/dr)
419 de8 = -s8i*c8/r8*(dfdab8 - 8._dp*fdab8/dr)
420 ELSE IF (idmp == 2) THEN
421 ! BJ
422 de6 = s6*c6*fdab6*fdab6*6.0_dp*dr**5
423 de8 = s8i*c8*fdab8*fdab8*8.0_dp*dr**7
424 ELSE
425 cpabort("Unknown DFT-D3 damping function:")
426 END IF
427 fdij(:) = (de6 + de8)*rij(:)/dr*fac
428 IF (dispersion_env%srb .AND. dr < 30.0d0) THEN
429 fdij(:) = fdij(:) + srbe*gsrb*dispersion_env%r0ab(za, zb)**t2srb*rij(:)/dr
430 END IF
431 atom_a = atom_of_kind(iatom)
432 atom_b = atom_of_kind(jatom)
433 force(ikind)%dispersion(:, atom_a) = force(ikind)%dispersion(:, atom_a) - fdij(:)
434 force(jkind)%dispersion(:, atom_b) = force(jkind)%dispersion(:, atom_b) + fdij(:)
435 IF (use_virial) THEN
436 CALL virial_pair_force(pv_virial_thread, -1._dp, fdij, rij)
437 END IF
438 ! forces from the r-dependence of the coordination numbers
439 IF (idmp == 1) THEN
440 ! zero
441 dc6a = -s6*fac*dc6a*fdab6/r6
442 dc6b = -s6*fac*dc6b*fdab6/r6
443 dc8a = -s8i*fac*dc8a*fdab8/r8
444 dc8b = -s8i*fac*dc8b*fdab8/r8
445 ELSE IF (idmp == 2) THEN
446 ! BJ
447 dc6a = -s6*fac*dc6a*fdab6
448 dc6b = -s6*fac*dc6b*fdab6
449 dc8a = -s8i*fac*dc8a*fdab8
450 dc8b = -s8i*fac*dc8b*fdab8
451 ELSE
452 cpabort("Unknown DFT-D3 damping function:")
453 END IF
454 DO i = 1, dcnum(iatom)%neighbors
455 katom = dcnum(iatom)%nlist(i)
456 kkind = kind_of(katom)
457 rik = dcnum(iatom)%rik(:, i)
458 drk = sqrt(sum(rik(:)**2))
459 fdik(:) = (dc6a + dc8a)*dcnum(iatom)%dvals(i)*rik(:)/drk
460 atom_c = atom_of_kind(katom)
461 force(ikind)%dispersion(:, atom_a) = force(ikind)%dispersion(:, atom_a) - fdik(:)
462 force(kkind)%dispersion(:, atom_c) = force(kkind)%dispersion(:, atom_c) + fdik(:)
463 IF (use_virial) THEN
464 CALL virial_pair_force(pv_virial_thread, -1._dp, fdik, rik)
465 END IF
466 END DO
467 DO i = 1, dcnum(jatom)%neighbors
468 katom = dcnum(jatom)%nlist(i)
469 kkind = kind_of(katom)
470 rik = dcnum(jatom)%rik(:, i)
471 drk = sqrt(sum(rik(:)**2))
472 fdik(:) = (dc6b + dc8b)*dcnum(jatom)%dvals(i)*rik(:)/drk
473 atom_c = atom_of_kind(katom)
474 force(jkind)%dispersion(:, atom_b) = force(jkind)%dispersion(:, atom_b) - fdik(:)
475 force(kkind)%dispersion(:, atom_c) = force(kkind)%dispersion(:, atom_c) + fdik(:)
476 IF (use_virial) THEN
477 CALL virial_pair_force(pv_virial_thread, -1._dp, fdik, rik)
478 END IF
479 END DO
480 END IF
481 IF (dispersion_env%doabc) THEN
482 CALL get_iterator_info(nl_iterator, cell=cell_b)
483 hashb = cellhash(cell_b, ncell)
484 is000 = (all(cell_b == 0))
485 rb0(:) = matmul(cell%hmat, cell_b)
486 ra(:) = pbc(particle_set(iatom)%r(:), cell)
487 rb(:) = pbc(particle_set(jatom)%r(:), cell) + rb0
488 r2ab = sum((ra - rb)**2)
489 DO icx = -ncell(1), ncell(1)
490 DO icy = -ncell(2), ncell(2)
491 DO icz = -ncell(3), ncell(3)
492 cell_c(1) = icx
493 cell_c(2) = icy
494 cell_c(3) = icz
495 hashc = cellhash(cell_c, ncell)
496 IF (is000 .AND. (all(cell_c == 0))) THEN
497 ! CASE 1: all atoms in (000), use only ordered triples
498 kstart = max(jatom + 1, iatom + 1)
499 fac0 = 1.0_dp
500 ELSE IF (is000) THEN
501 ! CASE 2: AB in (000), C in other cell
502 ! This case covers also all instances with BC in same
503 ! cell not (000)
504 kstart = 1
505 fac0 = 1.0_dp
506 ELSE
507 ! These are case 2 again, cycle
508 IF (hashc == hashb) cycle
509 IF (all(cell_c == 0)) cycle
510 ! CASE 3: A in (000) and B and C in different cells
511 kstart = 1
512 fac0 = 1.0_dp/3.0_dp
513 END IF
514 rc0 = matmul(cell%hmat, cell_c)
515 DO katom = kstart, natom
516 kkind = kind_of(katom)
517 IF (exclude(kkind) .OR. .NOT. dodisp(kkind)) cycle
518 rc(:) = rcpbc(:, katom) + rc0(:)
519 r2bc = sum((rb - rc)**2)
520 IF (r2bc >= rc2) cycle
521 r2ca = sum((rc - ra)**2)
522 IF (r2ca >= rc2) cycle
523 r2abc = r2ab*r2bc*r2ca
524 IF (r2abc <= 0.001_dp) cycle
525 IF (dispersion_env%nd3_exclude_pair > 0) THEN
526 CALL exclude_d3_kind_pair(dispersion_env%d3_exclude_pair, ikind, jkind, &
527 kkind, exclude_pair)
528 IF (exclude_pair) cycle
529 END IF
530 ! this is an empirical scaling
531 IF (r2abc <= 0.01*rc2*rc2*rc2) THEN
532 kkind = kind_of(katom)
533 atom_c = atom_of_kind(katom)
534 zc = atomnumber(kkind)
535 ! avoid double counting!
536 fac = 1._dp
537 IF (iatom == jatom .OR. iatom == katom .OR. jatom == katom) fac = 0.5_dp
538 IF (iatom == jatom .AND. iatom == katom) fac = 1._dp/3._dp
539 fac = fac*fac0
540 nabc = nabc + 1._dp
541 IF (dispersion_env%c9cnst) THEN
542 CALL getc6(maxc, max_elem, dispersion_env%c6ab, dispersion_env%maxci, za, zb, &
543 cnumfix(iatom), cnumfix(jatom), dispersion_env%k3, cc6ab, dcc6aba, dcc6abb)
544 CALL getc6(maxc, max_elem, dispersion_env%c6ab, dispersion_env%maxci, zb, zc, &
545 cnumfix(jatom), cnumfix(katom), dispersion_env%k3, cc6bc, dcc6bcb, dcc6bcc)
546 CALL getc6(maxc, max_elem, dispersion_env%c6ab, dispersion_env%maxci, zc, za, &
547 cnumfix(katom), cnumfix(iatom), dispersion_env%k3, cc6ca, dcc6cac, dcc6caa)
548 ELSE
549 CALL getc6(maxc, max_elem, dispersion_env%c6ab, dispersion_env%maxci, za, zb, &
550 cnumbers(iatom), cnumbers(jatom), dispersion_env%k3, cc6ab, dcc6aba, dcc6abb)
551 CALL getc6(maxc, max_elem, dispersion_env%c6ab, dispersion_env%maxci, zb, zc, &
552 cnumbers(jatom), cnumbers(katom), dispersion_env%k3, cc6bc, dcc6bcb, dcc6bcc)
553 CALL getc6(maxc, max_elem, dispersion_env%c6ab, dispersion_env%maxci, zc, za, &
554 cnumbers(katom), cnumbers(iatom), dispersion_env%k3, cc6ca, dcc6cac, dcc6caa)
555 END IF
556 c9 = -sqrt(cc6ab*cc6bc*cc6ca)
557 rabc = r2abc**(1._dp/6._dp)
558 r0 = (dispersion_env%r0ab(za, zb)*dispersion_env%r0ab(zb, zc)* &
559 dispersion_env%r0ab(zc, za))**(1._dp/3._dp)
560 ! bug fixed 3.10.2017
561 ! correct value from alp6=14 to 16 as used in original paper
562 CALL damping_d3(rabc, r0, 4._dp/3._dp, 16.0_dp, rcut, fdabc, dfdabc)
563 s1 = r2ab + r2bc - r2ca
564 s2 = r2ab + r2ca - r2bc
565 s3 = r2ca + r2bc - r2ab
566 ang = 0.375_dp*s1*s2*s3/r2abc + 1.0_dp
567
568 e9 = s9*fac*fdabc*c9*ang/r2abc**1.50d0
569 evdw = evdw - e9
570 e9tot = e9tot - e9
571 IF (atenergy) THEN
572 atener(iatom) = atener(iatom) - e9/3._dp
573 atener(jatom) = atener(jatom) - e9/3._dp
574 atener(katom) = atener(katom) - e9/3._dp
575 END IF
576 IF (atex) THEN
577 atevdw(iatom) = atevdw(iatom) - e9/3._dp
578 atevdw(jatom) = atevdw(jatom) - e9/3._dp
579 atevdw(katom) = atevdw(katom) - e9/3._dp
580 END IF
581
582 IF (calculate_forces) THEN
583 rab = rb - ra; rbc = rc - rb; rca = ra - rc
584 de91 = s9*fac*dfdabc*c9*ang/r2abc**1.50d0
585 de91 = -de91/3._dp*rabc + 3._dp*e9
586 dea = s9*fac*fdabc*c9/r2abc**2.50d0*0.75_dp
587 fdij(:) = de91*rab(:)/r2ab
588 fdij(:) = fdij(:) + dea*s1*s2*s3*rab(:)/r2ab
589 fdij(:) = fdij(:) - dea*(s2*s3 + s1*s3 - s1*s2)*rab(:)
590 force(ikind)%dispersion(:, atom_a) = force(ikind)%dispersion(:, atom_a) - fdij(:)
591 force(jkind)%dispersion(:, atom_b) = force(jkind)%dispersion(:, atom_b) + fdij(:)
592 IF (use_virial) THEN
593 CALL virial_pair_force(pv_virial_thread, -1._dp, fdij, rab)
594 END IF
595 fdij(:) = de91*rbc(:)/r2bc
596 fdij(:) = fdij(:) + dea*s1*s2*s3*rbc(:)/r2bc
597 fdij(:) = fdij(:) - dea*(s2*s3 - s1*s3 + s1*s2)*rbc(:)
598 force(jkind)%dispersion(:, atom_b) = force(jkind)%dispersion(:, atom_b) - fdij(:)
599 force(kkind)%dispersion(:, atom_c) = force(kkind)%dispersion(:, atom_c) + fdij(:)
600 IF (use_virial) THEN
601 CALL virial_pair_force(pv_virial_thread, -1._dp, fdij, rbc)
602 END IF
603 fdij(:) = de91*rca(:)/r2ca
604 fdij(:) = fdij(:) + dea*s1*s2*s3*rca(:)/r2ca
605 fdij(:) = fdij(:) - dea*(-s2*s3 + s1*s3 + s1*s2)*rca(:)
606 force(kkind)%dispersion(:, atom_c) = force(kkind)%dispersion(:, atom_c) - fdij(:)
607 force(ikind)%dispersion(:, atom_a) = force(ikind)%dispersion(:, atom_a) + fdij(:)
608 IF (use_virial) THEN
609 CALL virial_pair_force(pv_virial_thread, -1._dp, fdij, rca)
610 END IF
611
612 IF (.NOT. dispersion_env%c9cnst) THEN
613 ! forces from the r-dependence of the coordination numbers
614 ! atomic stress not implemented
615
616 de91 = 0.5_dp*e9/cc6ab
617 de921 = de91*dcc6aba
618 de922 = de91*dcc6abb
619 DO i = 1, dcnum(iatom)%neighbors
620 latom = dcnum(iatom)%nlist(i)
621 lkind = kind_of(latom)
622 rik(1) = dcnum(iatom)%rik(1, i)
623 rik(2) = dcnum(iatom)%rik(2, i)
624 rik(3) = dcnum(iatom)%rik(3, i)
625 drk = sqrt(rik(1)*rik(1) + rik(2)*rik(2) + rik(3)*rik(3))
626 fdik(:) = -de921*dcnum(iatom)%dvals(i)*rik(:)/drk
627 atom_d = atom_of_kind(latom)
628 force(ikind)%dispersion(:, atom_a) = force(ikind)%dispersion(:, atom_a) - fdik(:)
629 force(lkind)%dispersion(:, atom_d) = force(lkind)%dispersion(:, atom_d) + fdik(:)
630 IF (use_virial) THEN
631 CALL virial_pair_force(pv_virial_thread, -1._dp, fdik, rik)
632 END IF
633 END DO
634 DO i = 1, dcnum(jatom)%neighbors
635 latom = dcnum(jatom)%nlist(i)
636 lkind = kind_of(latom)
637 rik(1) = dcnum(jatom)%rik(1, i)
638 rik(2) = dcnum(jatom)%rik(2, i)
639 rik(3) = dcnum(jatom)%rik(3, i)
640 drk = sqrt(rik(1)*rik(1) + rik(2)*rik(2) + rik(3)*rik(3))
641 fdik(:) = -de922*dcnum(jatom)%dvals(i)*rik(:)/drk
642 atom_d = atom_of_kind(latom)
643 force(jkind)%dispersion(:, atom_b) = force(jkind)%dispersion(:, atom_b) - fdik(:)
644 force(lkind)%dispersion(:, atom_d) = force(lkind)%dispersion(:, atom_d) + fdik(:)
645 IF (use_virial) THEN
646 CALL virial_pair_force(pv_virial_thread, -1._dp, fdik, rik)
647 END IF
648 END DO
649
650 de91 = 0.5_dp*e9/cc6bc
651 de921 = de91*dcc6bcb
652 de922 = de91*dcc6bcc
653 DO i = 1, dcnum(jatom)%neighbors
654 latom = dcnum(jatom)%nlist(i)
655 lkind = kind_of(latom)
656 rik(1) = dcnum(jatom)%rik(1, i)
657 rik(2) = dcnum(jatom)%rik(2, i)
658 rik(3) = dcnum(jatom)%rik(3, i)
659 drk = sqrt(rik(1)*rik(1) + rik(2)*rik(2) + rik(3)*rik(3))
660 fdik(:) = -de921*dcnum(jatom)%dvals(i)*rik(:)/drk
661 atom_d = atom_of_kind(latom)
662 force(jkind)%dispersion(:, atom_b) = force(jkind)%dispersion(:, atom_b) - fdik(:)
663 force(lkind)%dispersion(:, atom_d) = force(lkind)%dispersion(:, atom_d) + fdik(:)
664 IF (use_virial) THEN
665 CALL virial_pair_force(pv_virial_thread, -1._dp, fdik, rik)
666 END IF
667 END DO
668 DO i = 1, dcnum(katom)%neighbors
669 latom = dcnum(katom)%nlist(i)
670 lkind = kind_of(latom)
671 rik(1) = dcnum(katom)%rik(1, i)
672 rik(2) = dcnum(katom)%rik(2, i)
673 rik(3) = dcnum(katom)%rik(3, i)
674 drk = sqrt(rik(1)*rik(1) + rik(2)*rik(2) + rik(3)*rik(3))
675 fdik(:) = -de922*dcnum(katom)%dvals(i)*rik(:)/drk
676 atom_d = atom_of_kind(latom)
677 force(kkind)%dispersion(:, atom_c) = force(kkind)%dispersion(:, atom_c) - fdik(:)
678 force(lkind)%dispersion(:, atom_d) = force(lkind)%dispersion(:, atom_d) + fdik(:)
679 IF (use_virial) THEN
680 CALL virial_pair_force(pv_virial_thread, -1._dp, fdik, rik)
681 END IF
682 END DO
683
684 de91 = 0.5_dp*e9/cc6ca
685 de921 = de91*dcc6cac
686 de922 = de91*dcc6caa
687 DO i = 1, dcnum(katom)%neighbors
688 latom = dcnum(katom)%nlist(i)
689 lkind = kind_of(latom)
690 rik(1) = dcnum(katom)%rik(1, i)
691 rik(2) = dcnum(katom)%rik(2, i)
692 rik(3) = dcnum(katom)%rik(3, i)
693 drk = sqrt(rik(1)*rik(1) + rik(2)*rik(2) + rik(3)*rik(3))
694 fdik(:) = -de921*dcnum(katom)%dvals(i)*rik(:)/drk
695 atom_d = atom_of_kind(latom)
696 force(kkind)%dispersion(:, atom_c) = force(kkind)%dispersion(:, atom_c) - fdik(:)
697 force(lkind)%dispersion(:, atom_d) = force(lkind)%dispersion(:, atom_d) + fdik(:)
698 IF (use_virial) THEN
699 CALL virial_pair_force(pv_virial_thread, -1._dp, fdik, rik)
700 END IF
701 END DO
702 DO i = 1, dcnum(iatom)%neighbors
703 latom = dcnum(iatom)%nlist(i)
704 lkind = kind_of(latom)
705 rik(1) = dcnum(iatom)%rik(1, i)
706 rik(2) = dcnum(iatom)%rik(2, i)
707 rik(3) = dcnum(iatom)%rik(3, i)
708 drk = sqrt(rik(1)*rik(1) + rik(2)*rik(2) + rik(3)*rik(3))
709 fdik(:) = -de922*dcnum(iatom)%dvals(i)*rik(:)/drk
710 atom_d = atom_of_kind(latom)
711 force(ikind)%dispersion(:, atom_a) = force(ikind)%dispersion(:, atom_a) - fdik(:)
712 force(lkind)%dispersion(:, atom_d) = force(lkind)%dispersion(:, atom_d) + fdik(:)
713 IF (use_virial) THEN
714 CALL virial_pair_force(pv_virial_thread, -1._dp, fdik, rik)
715 END IF
716 END DO
717 END IF
718
719 END IF
720
721 END IF
722 END DO
723 END DO
724 END DO
725 END DO
726
727 END IF
728 END IF
729 END IF
730 END DO
731
732 virial%pv_virial = virial%pv_virial + pv_virial_thread
733
734 CALL neighbor_list_iterator_release(nl_iterator)
735
736 elrc6 = 0._dp
737 elrc8 = 0._dp
738 elrc9 = 0._dp
739 ! Long range correction (atomic contributions not implemented)
740 IF (dispersion_env%lrc) THEN
741 ALLOCATE (cnkind(nkind))
742 cnkind = 0._dp
743 ! first use the default values
744 DO ikind = 1, nkind
745 CALL get_atomic_kind(atomic_kind_set(ikind), z=za)
746 cnkind(ikind) = dispersion_env%cn(za)
747 END DO
748 ! now check for changes from default
749 IF (ASSOCIATED(dispersion_env%cnkind)) THEN
750 DO i = 1, SIZE(dispersion_env%cnkind)
751 ikind = dispersion_env%cnkind(i)%kind
752 cnkind(ikind) = dispersion_env%cnkind(i)%cnum
753 END DO
754 END IF
755 DO ikind = 1, nkind
756 CALL get_atomic_kind(atomic_kind_set(ikind), natom=na, z=za)
757 CALL get_qs_kind(qs_kind_set(ikind), dispersion=disp_a, ghost=ghost_a, floating=floating_a)
758 IF (.NOT. disp_a%defined .OR. ghost_a .OR. floating_a) cycle
759 DO jkind = 1, nkind
760 CALL get_atomic_kind(atomic_kind_set(jkind), natom=nb, z=zb)
761 CALL get_qs_kind(qs_kind_set(jkind), dispersion=disp_b, ghost=ghost_b, floating=floating_b)
762 IF (.NOT. disp_b%defined .OR. ghost_b .OR. floating_b) cycle
763 IF (dispersion_env%nd3_exclude_pair > 0) THEN
764 CALL exclude_d3_kind_pair(dispersion_env%d3_exclude_pair, ikind, jkind, &
765 exclude=exclude_pair)
766 IF (exclude_pair) cycle
767 END IF
768 CALL getc6(maxc, max_elem, dispersion_env%c6ab, dispersion_env%maxci, za, zb, &
769 cnkind(ikind), cnkind(jkind), dispersion_env%k3, cc6ab, dcc6aba, dcc6abb)
770 elrc6 = elrc6 - s6*twopi*real(na*nb, kind=dp)*cc6ab/(3._dp*rcut**3*cell%deth)
771 c8 = 3.0d0*cc6ab*dispersion_env%r2r4(za)*dispersion_env%r2r4(zb)
772 elrc8 = elrc8 - s8*twopi*real(na*nb, kind=dp)*c8/(5._dp*rcut**5*cell%deth)
773 IF (dispersion_env%doabc) THEN
774 DO kkind = 1, nkind
775 CALL get_atomic_kind(atomic_kind_set(kkind), natom=nc, z=zc)
776 CALL get_qs_kind(qs_kind_set(kkind), dispersion=disp_c, ghost=ghost_c, floating=floating_c)
777 IF (.NOT. disp_c%defined .OR. ghost_c .OR. floating_c) cycle
778 IF (dispersion_env%nd3_exclude_pair > 0) THEN
779 CALL exclude_d3_kind_pair(dispersion_env%d3_exclude_pair, ikind, jkind, kkind, &
780 exclude_pair)
781 IF (exclude_pair) cycle
782 END IF
783 CALL getc6(maxc, max_elem, dispersion_env%c6ab, dispersion_env%maxci, za, zb, &
784 cnkind(ikind), cnkind(jkind), dispersion_env%k3, cc6ab, dcc6aba, dcc6abb)
785 CALL getc6(maxc, max_elem, dispersion_env%c6ab, dispersion_env%maxci, zc, za, &
786 cnkind(kkind), cnkind(ikind), dispersion_env%k3, cc6ca, dcc6aba, dcc6abb)
787 CALL getc6(maxc, max_elem, dispersion_env%c6ab, dispersion_env%maxci, zb, zc, &
788 cnkind(jkind), cnkind(kkind), dispersion_env%k3, cc6bc, dcc6aba, dcc6abb)
789 c9 = -sqrt(cc6ab*cc6bc*cc6ca)
790 elrc9 = elrc9 - s9*64._dp*twopi*real(na*nb*nc, kind=dp)*c9/(6._dp*rcut**3*cell%deth**2)
791 END DO
792 END IF
793 END DO
794 END DO
795 IF (use_virial) THEN
796 IF (para_env%is_source()) THEN
797 DO i = 1, 3
798 virial%pv_virial(i, i) = virial%pv_virial(i, i) + (elrc6 + elrc8 + 2._dp*elrc9)
799 END DO
800 END IF
801 END IF
802 DEALLOCATE (cnkind)
803 END IF
804
805 DEALLOCATE (cnumbers)
806 IF (dispersion_env%doabc .AND. dispersion_env%c9cnst) THEN
807 DEALLOCATE (cnumfix)
808 END IF
809 IF (calculate_forces .OR. debugall) THEN
810 DO iatom = 1, natom
811 DEALLOCATE (dcnum(iatom)%nlist, dcnum(iatom)%dvals, dcnum(iatom)%rik)
812 END DO
813 DEALLOCATE (dcnum)
814 ELSE
815 DEALLOCATE (dcnum)
816 END IF
817
818 ! set dispersion energy
819
820 CALL para_env%sum(e6tot)
821 CALL para_env%sum(e8tot)
822 CALL para_env%sum(e9tot)
823 CALL para_env%sum(evdw)
824 CALL para_env%sum(nab)
825 CALL para_env%sum(nabc)
826 e6tot = e6tot + elrc6
827 e8tot = e8tot + elrc8
828 e9tot = e9tot + elrc9
829 ! For printing, we need all contributions
830 evdw = evdw + (elrc6 + elrc8 + elrc9)
831 IF (unit_nr > 0) THEN
832 WRITE (unit_nr, "(A,F20.0)") " E6 vdW terms :", nab
833 WRITE (unit_nr, *) " E6 vdW energy [au/kcal] :", e6tot, e6tot*kcalmol
834 WRITE (unit_nr, *) " E8 vdW energy [au/kcal] :", e8tot, e8tot*kcalmol
835 WRITE (unit_nr, *) " %E8 on total vdW energy :", e8tot/evdw*100._dp
836 WRITE (unit_nr, "(A,F20.0)") " E9 vdW terms :", nabc
837 WRITE (unit_nr, *) " E9 vdW energy [au/kcal] :", e9tot, e9tot*kcalmol
838 WRITE (unit_nr, *) " %E9 on total vdW energy :", e9tot/evdw*100._dp
839 IF (dispersion_env%lrc) THEN
840 WRITE (unit_nr, *) " E LRC C6 [au/kcal] :", elrc6, elrc6*kcalmol
841 WRITE (unit_nr, *) " E LRC C8 [au/kcal] :", elrc8, elrc8*kcalmol
842 WRITE (unit_nr, *) " E LRC C9 [au/kcal] :", elrc9, elrc9*kcalmol
843 END IF
844 END IF
845
846 evdw = evdw/para_env%num_pe
847
848 DEALLOCATE (dodisp, exclude, atomnumber, rcpbc, radd2, c6d2)
849
850 IF (domol) THEN
851 DEALLOCATE (atom2mol)
852 END IF
853
854 CALL timestop(handle)
855
857
858! **************************************************************************************************
859!> \brief ...
860!> \param c6ab ...
861!> \param maxci ...
862!> \param filename ...
863!> \param para_env ...
864! **************************************************************************************************
865 SUBROUTINE dftd3_c6_param(c6ab, maxci, filename, para_env)
866
867 REAL(kind=dp), DIMENSION(:, :, :, :, :) :: c6ab
868 INTEGER, DIMENSION(:) :: maxci
869 CHARACTER(LEN=*) :: filename
870 TYPE(mp_para_env_type), POINTER :: para_env
871
872 INTEGER :: funit, iadr, iat, jadr, jat, kk, nl, &
873 nlines, nn, ref_stride
874 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: pars
875
876 IF (para_env%is_source()) THEN
877 ! Read the DFT-D3 C6AB parameters from file "filename"
878 CALL open_file(file_name=filename, unit_number=funit, file_form="FORMATTED")
879 READ (funit, *) nl, nlines
880 END IF
881 CALL para_env%bcast(nl)
882 CALL para_env%bcast(nlines)
883 ALLOCATE (pars(nl))
884 IF (para_env%is_source()) THEN
885 READ (funit, *) pars(1:nl)
886 CALL close_file(unit_number=funit)
887 END IF
888 CALL para_env%bcast(pars)
889
890! Store C6AB coefficients in an array
891 c6ab = -1._dp
892 maxci = 0
893 ref_stride = get_ref_stride(pars, nlines)
894 kk = 1
895 DO nn = 1, nlines
896 iat = nint(pars(kk + 1))
897 jat = nint(pars(kk + 2))
898 CALL limit(iat, jat, iadr, jadr, ref_stride)
899 maxci(iat) = max(maxci(iat), iadr)
900 maxci(jat) = max(maxci(jat), jadr)
901 c6ab(iat, jat, iadr, jadr, 1) = pars(kk)
902 c6ab(iat, jat, iadr, jadr, 2) = pars(kk + 3)
903 c6ab(iat, jat, iadr, jadr, 3) = pars(kk + 4)
904
905 c6ab(jat, iat, jadr, iadr, 1) = pars(kk)
906 c6ab(jat, iat, jadr, iadr, 2) = pars(kk + 4)
907 c6ab(jat, iat, jadr, iadr, 3) = pars(kk + 3)
908 kk = (nn*5) + 1
909 END DO
910
911 DEALLOCATE (pars)
912
913 END SUBROUTINE dftd3_c6_param
914
915! **************************************************************************************************
916!> \brief Detects the reference-state encoding used in the DFT-D3 C6AB table.
917!> \param pars DFT-D3 C6AB parameter table.
918!> \param nlines Number of C6AB parameter lines.
919!> \return Reference-state stride.
920! **************************************************************************************************
921 FUNCTION get_ref_stride(pars, nlines) RESULT(ref_stride)
922 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: pars
923 INTEGER, INTENT(IN) :: nlines
924 INTEGER :: ref_stride
925
926 INTEGER :: kk, nn
927
928 ref_stride = 100
929 kk = 1
930 DO nn = 1, nlines
931 IF (nint(pars(kk + 1)) > 1000 .OR. nint(pars(kk + 2)) > 1000) THEN
932 ref_stride = 1000
933 EXIT
934 END IF
935 kk = (nn*5) + 1
936 END DO
937
938 END FUNCTION get_ref_stride
939
940! **************************************************************************************************
941!> \brief Decodes element numbers and reference-state indices.
942!> \param iat Encoded first element number.
943!> \param jat Encoded second element number.
944!> \param iadr First reference-state index.
945!> \param jadr Second reference-state index.
946!> \param ref_stride Reference-state stride.
947! **************************************************************************************************
948 SUBROUTINE limit(iat, jat, iadr, jadr, ref_stride)
949 INTEGER :: iat, jat, iadr, jadr, ref_stride
950
951 iadr = 1
952 jadr = 1
953 DO WHILE (iat > ref_stride)
954 iat = iat - ref_stride
955 iadr = iadr + 1
956 END DO
957
958 DO WHILE (jat > ref_stride)
959 jat = jat - ref_stride
960 jadr = jadr + 1
961 END DO
962 END SUBROUTINE limit
963
964! **************************************************************************************************
965!> \brief ...
966!> \param rab ...
967!> \param rcutab ...
968!> \param srn ...
969!> \param alpn ...
970!> \param rcut ...
971!> \param fdab ...
972!> \param dfdab ...
973! **************************************************************************************************
974 SUBROUTINE damping_d3(rab, rcutab, srn, alpn, rcut, fdab, dfdab)
975
976 REAL(kind=dp), INTENT(IN) :: rab, rcutab, srn, alpn, rcut
977 REAL(kind=dp), INTENT(OUT) :: fdab, dfdab
978
979 REAL(kind=dp) :: a, b, c, d, dd, dfab, dfcc, dz, fab, &
980 fcc, rl, rr, ru, z, zz
981
982 rl = rcut - 1._dp
983 ru = rcut
984 IF (rab >= ru) THEN
985 fcc = 0._dp
986 dfcc = 0._dp
987 ELSEIF (rab <= rl) THEN
988 fcc = 1._dp
989 dfcc = 0._dp
990 ELSE
991 z = rab*rab - rl*rl
992 dz = 2._dp*rab
993 zz = z*z*z
994 d = ru*ru - rl*rl
995 dd = d*d*d
996 a = -10._dp/dd
997 b = 15._dp/(dd*d)
998 c = -6._dp/(dd*d*d)
999 fcc = 1._dp + zz*(a + b*z + c*z*z)
1000 dfcc = zz*dz/z*(3._dp*a + 4._dp*b*z + 5._dp*c*z*z)
1001 END IF
1002
1003 rr = 6._dp*(rab/(srn*rcutab))**(-alpn)
1004 fab = 1._dp/(1._dp + rr)
1005 dfab = fab*fab*rr*alpn/rab
1006 fdab = fab*fcc
1007 dfdab = dfab*fcc + fab*dfcc
1008
1009 END SUBROUTINE damping_d3
1010
1011! **************************************************************************************************
1012!> \brief ...
1013!> \param maxc ...
1014!> \param max_elem ...
1015!> \param c6ab ...
1016!> \param mxc ...
1017!> \param iat ...
1018!> \param jat ...
1019!> \param nci ...
1020!> \param ncj ...
1021!> \param k3 ...
1022!> \param c6 ...
1023!> \param dc6a ...
1024!> \param dc6b ...
1025! **************************************************************************************************
1026 SUBROUTINE getc6(maxc, max_elem, c6ab, mxc, iat, jat, nci, ncj, k3, c6, dc6a, dc6b)
1027
1028 INTEGER, INTENT(IN) :: maxc, max_elem
1029 REAL(kind=dp), INTENT(IN) :: c6ab(max_elem, max_elem, maxc, maxc, 3)
1030 INTEGER, INTENT(IN) :: mxc(max_elem), iat, jat
1031 REAL(kind=dp), INTENT(IN) :: nci, ncj, k3
1032 REAL(kind=dp), INTENT(OUT) :: c6, dc6a, dc6b
1033
1034 INTEGER :: i, j
1035 REAL(kind=dp) :: c6mem, cn1, cn2, csum, dtmpa, dtmpb, &
1036 dwa, dwb, dza, dzb, r, rsave, rsum, &
1037 tmp1
1038
1039! the exponential is sensitive to numerics
1040! when nci or ncj is much larger than cn1/cn2
1041
1042 c6mem = -1.0e+99_dp
1043 rsave = 1.0e+99_dp
1044 rsum = 0.0_dp
1045 csum = 0.0_dp
1046 dza = 0.0_dp
1047 dzb = 0.0_dp
1048 dwa = 0.0_dp
1049 dwb = 0.0_dp
1050 c6 = 0.0_dp
1051 DO i = 1, mxc(iat)
1052 DO j = 1, mxc(jat)
1053 c6 = c6ab(iat, jat, i, j, 1)
1054 IF (c6 > 0.0_dp) THEN
1055 cn1 = c6ab(iat, jat, i, j, 2)
1056 cn2 = c6ab(iat, jat, i, j, 3)
1057 ! distance
1058 r = (cn1 - nci)**2 + (cn2 - ncj)**2
1059 IF (r < rsave) THEN
1060 rsave = r
1061 c6mem = c6
1062 END IF
1063 tmp1 = exp(k3*r)
1064 dtmpa = -2.0_dp*k3*(cn1 - nci)*tmp1
1065 dtmpb = -2.0_dp*k3*(cn2 - ncj)*tmp1
1066 rsum = rsum + tmp1
1067 csum = csum + tmp1*c6
1068 dza = dza + dtmpa*c6
1069 dwa = dwa + dtmpa
1070 dzb = dzb + dtmpb*c6
1071 dwb = dwb + dtmpb
1072 END IF
1073 END DO
1074 END DO
1075
1076 IF (c6 == 0.0_dp) c6mem = 0.0_dp
1077
1078 IF (rsum > 1.0e-66_dp) THEN
1079 c6 = csum/rsum
1080 dc6a = (dza - c6*dwa)/rsum
1081 dc6b = (dzb - c6*dwb)/rsum
1082 ELSE
1083 c6 = c6mem
1084 dc6a = 0._dp
1085 dc6b = 0._dp
1086 END IF
1087
1088 END SUBROUTINE getc6
1089
1090END MODULE qs_dispersion_d3
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind_set(atomic_kind_set, atom_of_kind, kind_of, natom_of_kind, maxatom, natom, nshell, fist_potential_present, shell_present, shell_adiabatic, shell_check_distance, damping_present)
Get attributes of an atomic kind set.
subroutine, public get_atomic_kind(atomic_kind, fist_potential, element_symbol, name, mass, kind_number, natom, atom_list, rcov, rvdw, z, qeff, apol, cpol, mm_radius, shell, shell_active, damping)
Get attributes of an atomic kind.
Holds information on atomic properties.
subroutine, public atprop_array_init(atarray, natom)
...
Handles all functions related to the CELL.
Definition cell_types.F:15
subroutine, public get_cell(cell, alpha, beta, gamma, deth, orthorhombic, abc, periodic, h, h_inv, symmetry_id, tag)
Get informations about a simulation cell.
Definition cell_types.F:210
real(kind=dp) function, public plane_distance(h, k, l, cell)
Calculate the distance between two lattice planes as defined by a triple of Miller indices (hkl).
Definition cell_types.F:301
Utility routines to open and close files. Tracking of preconnections.
Definition cp_files.F:16
subroutine, public open_file(file_name, file_status, file_form, file_action, file_position, file_pad, unit_number, debug, skip_get_unit_number, file_access)
Opens the requested file using a free unit number.
Definition cp_files.F:311
subroutine, public close_file(unit_number, file_status, keep_preconnection)
Close an open file given by its logical unit number. Optionally, keep the file and unit preconnected.
Definition cp_files.F:122
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public vdw_pairpot_dftd3
integer, parameter, public vdw_pairpot_dftd3bj
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Definition of mathematical constants and functions.
real(kind=dp), parameter, public twopi
real(kind=dp), dimension(0:maxfac), parameter, public fac
Interface to the message passing library MPI.
Define the data structure for the molecule information.
Define the data structure for the particle information.
Definition of physical constants:
Definition physcon.F:68
real(kind=dp), parameter, public kcalmol
Definition physcon.F:171
Coordination number routines for dispersion pairpotentials.
subroutine, public exclude_d3_kind_pair(exclude_list, za, zb, zc, exclude)
...
subroutine, public d3_cnumber(qs_env, dispersion_env, cnumbers, dcnum, exclude, atomnumber, derivatives, cnfun)
...
subroutine, public dcnum_distribute(dcnum, para_env)
...
Calculation of D3 dispersion.
subroutine, public dftd3_c6_param(c6ab, maxci, filename, para_env)
...
subroutine, public calculate_dispersion_d3_pairpot(qs_env, dispersion_env, evdw, calculate_forces, unit_nr, atevdw)
...
Definition of disperson types for DFT calculations.
integer, parameter, public dftd3_pp
Set disperson types for DFT calculations.
integer function, public cellhash(cell, ncell)
...
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, mimic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, xcint_weights, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
Define the quickstep kind type and their sub types.
subroutine, public get_qs_kind(qs_kind, basis_set, basis_type, ncgf, nsgf, all_potential, tnadd_potential, gth_potential, sgp_potential, upf_potential, cneo_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zatom, zeff, elec_conf, mao, lmax_dftb, alpha_core_charge, ccore_charge, core_charge, core_charge_radius, paw_proj_set, paw_atom, hard_radius, hard0_radius, max_rad_local, covalent_radius, vdw_radius, gpw_type_forced, harmonics, max_iso_not0, max_s_harm, grid_atom, ngrid_ang, ngrid_rad, lmax_rho0, dft_plus_u_atom, l_of_dft_plus_u, n_of_dft_plus_u, u_minus_j, u_of_dft_plus_u, j_of_dft_plus_u, alpha_of_dft_plus_u, beta_of_dft_plus_u, j0_of_dft_plus_u, occupation_of_dft_plus_u, dispersion, bs_occupation, magnetization, no_optimize, addel, laddel, naddel, orbitals, max_scf, eps_scf, smear, u_ramping, u_minus_j_target, eps_u_ramping, init_u_ramping_each_scf, reltmat, ghost, monovalent, floating, name, element_symbol, pao_basis_size, pao_model_file, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
Define the neighbor list data types and the corresponding functionality.
subroutine, public neighbor_list_iterator_create(iterator_set, nl, search, nthread)
Neighbor list iterator functions.
subroutine, public neighbor_list_iterator_release(iterator_set)
...
integer function, public neighbor_list_iterate(iterator_set, mepos)
...
subroutine, public get_iterator_info(iterator_set, mepos, ikind, jkind, nkind, ilist, nlist, inode, nnode, iatom, jatom, r, cell)
...
pure subroutine, public virial_pair_force(pv_virial, f0, force, rab)
Computes the contribution to the stress tensor from two-body pair-wise forces.
Provides all information about an atomic kind.
type for the atomic properties
Type defining parameters related to the simulation cell.
Definition cell_types.F:60
stores all the informations relevant to an mpi environment
Provides all information about a quickstep kind.