(git:b77b4be)
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-2025 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 ! for parallel runs we have to update dcnum on all processors
264 IF (calculate_forces .OR. debugall) THEN
265 CALL dcnum_distribute(dcnum, para_env)
266 IF (unit_nr > 0 .AND. SIZE(dcnum) > 0) THEN
267 WRITE (unit_nr, *)
268 WRITE (unit_nr, *) " ATOM Coordination Neighbors"
269 DO i = 1, natom
270 WRITE (unit_nr, "(I6,F20.10,I12)") i, cnumbers(i), dcnum(i)%neighbors
271 END DO
272 WRITE (unit_nr, *)
273 END IF
274 END IF
275
276 nab = 0._dp
277 nabc = 0._dp
278 IF (dispersion_env%doabc) THEN
279 rcc = 2._dp*dispersion_env%rc_disp
280 CALL get_cell(cell=cell, periodic=periodic)
281 sab_max(1) = rcc/plane_distance(1, 0, 0, cell)
282 sab_max(2) = rcc/plane_distance(0, 1, 0, cell)
283 sab_max(3) = rcc/plane_distance(0, 0, 1, cell)
284 ncell(:) = (int(sab_max(:)) + 1)*periodic(:)
285 IF (unit_nr > 0) THEN
286 WRITE (unit_nr, *) " Calculate C9 Terms"
287 WRITE (unit_nr, "(A,T20,I3,A,I3)") " Search in cells ", -ncell(1), ":", ncell(1)
288 WRITE (unit_nr, "(T20,I3,A,I3)") - ncell(2), ":", ncell(2)
289 WRITE (unit_nr, "(T20,I3,A,I3)") - ncell(3), ":", ncell(3)
290 WRITE (unit_nr, *)
291 END IF
292 IF (dispersion_env%c9cnst) THEN
293 IF (unit_nr > 0) WRITE (unit_nr, *) " Use reference coordination numbers for C9 term"
294 ALLOCATE (cnumfix(natom))
295 cnumfix = 0._dp
296 ! first use the default values
297 DO iatom = 1, natom
298 ikind = kind_of(iatom)
299 CALL get_atomic_kind(atomic_kind_set(ikind), z=za)
300 cnumfix(iatom) = dispersion_env%cn(za)
301 END DO
302 ! now check for changes from default
303 IF (ASSOCIATED(dispersion_env%cnkind)) THEN
304 DO i = 1, SIZE(dispersion_env%cnkind)
305 ikind = dispersion_env%cnkind(i)%kind
306 cnum = dispersion_env%cnkind(i)%cnum
307 cpassert(ikind <= nkind)
308 cpassert(ikind > 0)
309 CALL get_atomic_kind(atomic_kind_set(ikind), natom=na, atom_list=atom_list)
310 DO ia = 1, na
311 iatom = atom_list(ia)
312 cnumfix(iatom) = cnum
313 END DO
314 END DO
315 END IF
316 IF (ASSOCIATED(dispersion_env%cnlist)) THEN
317 DO i = 1, SIZE(dispersion_env%cnlist)
318 DO ilist = 1, dispersion_env%cnlist(i)%natom
319 iatom = dispersion_env%cnlist(i)%atom(ilist)
320 cnumfix(iatom) = dispersion_env%cnlist(i)%cnum
321 END DO
322 END DO
323 END IF
324 IF (unit_nr > 0) THEN
325 DO i = 1, natom
326 IF (abs(cnumbers(i) - cnumfix(i)) > 0.5_dp) THEN
327 WRITE (unit_nr, "(A,T20,A,I6,T41,2F10.3)") " Difference in CN ", "Atom:", &
328 i, cnumbers(i), cnumfix(i)
329 END IF
330 END DO
331 WRITE (unit_nr, *)
332 END IF
333 END IF
334 END IF
335
336 sab_vdw => dispersion_env%sab_vdw
337
338 num_pe = 1
339 CALL neighbor_list_iterator_create(nl_iterator, sab_vdw, nthread=num_pe)
340
341 mepos = 0
342 DO WHILE (neighbor_list_iterate(nl_iterator, mepos=mepos) == 0)
343 CALL get_iterator_info(nl_iterator, mepos=mepos, ikind=ikind, jkind=jkind, iatom=iatom, jatom=jatom, r=rij)
344
345 IF (exclude(ikind) .OR. exclude(jkind)) cycle
346
347 IF (.NOT. (dodisp(ikind) .AND. dodisp(jkind))) cycle
348
349 za = atomnumber(ikind)
350 zb = atomnumber(jkind)
351 ! vdW potential
352 dr = sqrt(sum(rij(:)**2))
353 IF (dr <= rcut) THEN
354 nab = nab + 1._dp
355 fac = 1._dp
356 IF (iatom == jatom) fac = 0.5_dp
357 IF (disp_a%type == dftd3_pp .AND. dr > 0.001_dp) THEN
358 IF (dispersion_env%nd3_exclude_pair > 0) THEN
359 CALL exclude_d3_kind_pair(dispersion_env%d3_exclude_pair, ikind, jkind, &
360 exclude=exclude_pair)
361 IF (exclude_pair) cycle
362 END IF
363 ! C6 coefficient
364 CALL getc6(maxc, max_elem, dispersion_env%c6ab, dispersion_env%maxci, za, zb, &
365 cnumbers(iatom), cnumbers(jatom), dispersion_env%k3, c6, dc6a, dc6b)
366 c8 = 3.0d0*c6*dispersion_env%r2r4(za)*dispersion_env%r2r4(zb)
367 dc8a = 3.0d0*dc6a*dispersion_env%r2r4(za)*dispersion_env%r2r4(zb)
368 dc8b = 3.0d0*dc6b*dispersion_env%r2r4(za)*dispersion_env%r2r4(zb)
369 r6 = dr**6
370 r8 = r6*dr*dr
371 s8i = s8
372 IF (domol) THEN
373 IF (atom2mol(iatom) /= atom2mol(jatom)) THEN
374 s8i = kgc8
375 END IF
376 END IF
377 ! damping
378 IF (idmp == 1) THEN
379 ! zero
380 CALL damping_d3(dr, dispersion_env%r0ab(za, zb), rs6, alp6, rcut, fdab6, dfdab6)
381 CALL damping_d3(dr, dispersion_env%r0ab(za, zb), rs8, alp8, rcut, fdab8, dfdab8)
382 e6 = s6*fac*c6*fdab6/r6
383 e8 = s8i*fac*c8*fdab8/r8
384 ELSE IF (idmp == 2) THEN
385 ! BJ
386 r0ab = sqrt(3.0d0*dispersion_env%r2r4(za)*dispersion_env%r2r4(zb))
387 f0ab = a1*r0ab + a2
388 fdab6 = 1.0_dp/(r6 + f0ab**6)
389 fdab8 = 1.0_dp/(r8 + f0ab**8)
390 e6 = s6*fac*c6*fdab6
391 e8 = s8i*fac*c8*fdab8
392 ELSE
393 cpabort("Unknown DFT-D3 damping function:")
394 END IF
395 IF (dispersion_env%srb .AND. dr .LT. 30.0d0) THEN
396 srbe = ssrb*(real((za*zb), kind=dp))**t1srb*exp(-gsrb*dr*dispersion_env%r0ab(za, zb)**t2srb)
397 esrb = esrb + srbe
398 evdw = evdw - srbe
399 ELSE
400 srbe = 0.0_dp
401 END IF
402 evdw = evdw - e6 - e8
403 e6tot = e6tot - e6
404 e8tot = e8tot - e8
405 IF (atenergy) THEN
406 atener(iatom) = atener(iatom) - 0.5_dp*(e6 + e8 + srbe)
407 atener(jatom) = atener(jatom) - 0.5_dp*(e6 + e8 + srbe)
408 END IF
409 IF (atex) THEN
410 atevdw(iatom) = atevdw(iatom) - 0.5_dp*(e6 + e8 + srbe)
411 atevdw(jatom) = atevdw(jatom) - 0.5_dp*(e6 + e8 + srbe)
412 END IF
413 IF (calculate_forces) THEN
414 ! damping
415 IF (idmp == 1) THEN
416 ! zero
417 de6 = -s6*c6/r6*(dfdab6 - 6._dp*fdab6/dr)
418 de8 = -s8i*c8/r8*(dfdab8 - 8._dp*fdab8/dr)
419 ELSE IF (idmp == 2) THEN
420 ! BJ
421 de6 = s6*c6*fdab6*fdab6*6.0_dp*dr**5
422 de8 = s8i*c8*fdab8*fdab8*8.0_dp*dr**7
423 ELSE
424 cpabort("Unknown DFT-D3 damping function:")
425 END IF
426 fdij(:) = (de6 + de8)*rij(:)/dr*fac
427 IF (dispersion_env%srb .AND. dr .LT. 30.0d0) THEN
428 fdij(:) = fdij(:) + srbe*gsrb*dispersion_env%r0ab(za, zb)**t2srb*rij(:)/dr
429 END IF
430 atom_a = atom_of_kind(iatom)
431 atom_b = atom_of_kind(jatom)
432 force(ikind)%dispersion(:, atom_a) = force(ikind)%dispersion(:, atom_a) - fdij(:)
433 force(jkind)%dispersion(:, atom_b) = force(jkind)%dispersion(:, atom_b) + fdij(:)
434 IF (use_virial) THEN
435 CALL virial_pair_force(pv_virial_thread, -1._dp, fdij, rij)
436 END IF
437 ! forces from the r-dependence of the coordination numbers
438 IF (idmp == 1) THEN
439 ! zero
440 dc6a = -s6*fac*dc6a*fdab6/r6
441 dc6b = -s6*fac*dc6b*fdab6/r6
442 dc8a = -s8i*fac*dc8a*fdab8/r8
443 dc8b = -s8i*fac*dc8b*fdab8/r8
444 ELSE IF (idmp == 2) THEN
445 ! BJ
446 dc6a = -s6*fac*dc6a*fdab6
447 dc6b = -s6*fac*dc6b*fdab6
448 dc8a = -s8i*fac*dc8a*fdab8
449 dc8b = -s8i*fac*dc8b*fdab8
450 ELSE
451 cpabort("Unknown DFT-D3 damping function:")
452 END IF
453 DO i = 1, dcnum(iatom)%neighbors
454 katom = dcnum(iatom)%nlist(i)
455 kkind = kind_of(katom)
456 rik = dcnum(iatom)%rik(:, i)
457 drk = sqrt(sum(rik(:)**2))
458 fdik(:) = (dc6a + dc8a)*dcnum(iatom)%dvals(i)*rik(:)/drk
459 atom_c = atom_of_kind(katom)
460 force(ikind)%dispersion(:, atom_a) = force(ikind)%dispersion(:, atom_a) - fdik(:)
461 force(kkind)%dispersion(:, atom_c) = force(kkind)%dispersion(:, atom_c) + fdik(:)
462 IF (use_virial) THEN
463 CALL virial_pair_force(pv_virial_thread, -1._dp, fdik, rik)
464 END IF
465 END DO
466 DO i = 1, dcnum(jatom)%neighbors
467 katom = dcnum(jatom)%nlist(i)
468 kkind = kind_of(katom)
469 rik = dcnum(jatom)%rik(:, i)
470 drk = sqrt(sum(rik(:)**2))
471 fdik(:) = (dc6b + dc8b)*dcnum(jatom)%dvals(i)*rik(:)/drk
472 atom_c = atom_of_kind(katom)
473 force(jkind)%dispersion(:, atom_b) = force(jkind)%dispersion(:, atom_b) - fdik(:)
474 force(kkind)%dispersion(:, atom_c) = force(kkind)%dispersion(:, atom_c) + fdik(:)
475 IF (use_virial) THEN
476 CALL virial_pair_force(pv_virial_thread, -1._dp, fdik, rik)
477 END IF
478 END DO
479 END IF
480 IF (dispersion_env%doabc) THEN
481 CALL get_iterator_info(nl_iterator, cell=cell_b)
482 hashb = cellhash(cell_b, ncell)
483 is000 = (all(cell_b == 0))
484 rb0(:) = matmul(cell%hmat, cell_b)
485 ra(:) = pbc(particle_set(iatom)%r(:), cell)
486 rb(:) = pbc(particle_set(jatom)%r(:), cell) + rb0
487 r2ab = sum((ra - rb)**2)
488 DO icx = -ncell(1), ncell(1)
489 DO icy = -ncell(2), ncell(2)
490 DO icz = -ncell(3), ncell(3)
491 cell_c(1) = icx
492 cell_c(2) = icy
493 cell_c(3) = icz
494 hashc = cellhash(cell_c, ncell)
495 IF (is000 .AND. (all(cell_c == 0))) THEN
496 ! CASE 1: all atoms in (000), use only ordered triples
497 kstart = max(jatom + 1, iatom + 1)
498 fac0 = 1.0_dp
499 ELSE IF (is000) THEN
500 ! CASE 2: AB in (000), C in other cell
501 ! This case covers also all instances with BC in same
502 ! cell not (000)
503 kstart = 1
504 fac0 = 1.0_dp
505 ELSE
506 ! These are case 2 again, cycle
507 IF (hashc == hashb) cycle
508 IF (all(cell_c == 0)) cycle
509 ! CASE 3: A in (000) and B and C in different cells
510 kstart = 1
511 fac0 = 1.0_dp/3.0_dp
512 END IF
513 rc0 = matmul(cell%hmat, cell_c)
514 DO katom = kstart, natom
515 kkind = kind_of(katom)
516 IF (exclude(kkind) .OR. .NOT. dodisp(kkind)) cycle
517 rc(:) = rcpbc(:, katom) + rc0(:)
518 r2bc = sum((rb - rc)**2)
519 IF (r2bc >= rc2) cycle
520 r2ca = sum((rc - ra)**2)
521 IF (r2ca >= rc2) cycle
522 r2abc = r2ab*r2bc*r2ca
523 IF (r2abc <= 0.001_dp) cycle
524 IF (dispersion_env%nd3_exclude_pair > 0) THEN
525 CALL exclude_d3_kind_pair(dispersion_env%d3_exclude_pair, ikind, jkind, &
526 kkind, exclude_pair)
527 IF (exclude_pair) cycle
528 END IF
529 ! this is an empirical scaling
530 IF (r2abc <= 0.01*rc2*rc2*rc2) THEN
531 kkind = kind_of(katom)
532 atom_c = atom_of_kind(katom)
533 zc = atomnumber(kkind)
534 ! avoid double counting!
535 fac = 1._dp
536 IF (iatom == jatom .OR. iatom == katom .OR. jatom == katom) fac = 0.5_dp
537 IF (iatom == jatom .AND. iatom == katom) fac = 1._dp/3._dp
538 fac = fac*fac0
539 nabc = nabc + 1._dp
540 IF (dispersion_env%c9cnst) THEN
541 CALL getc6(maxc, max_elem, dispersion_env%c6ab, dispersion_env%maxci, za, zb, &
542 cnumfix(iatom), cnumfix(jatom), dispersion_env%k3, cc6ab, dcc6aba, dcc6abb)
543 CALL getc6(maxc, max_elem, dispersion_env%c6ab, dispersion_env%maxci, zb, zc, &
544 cnumfix(jatom), cnumfix(katom), dispersion_env%k3, cc6bc, dcc6bcb, dcc6bcc)
545 CALL getc6(maxc, max_elem, dispersion_env%c6ab, dispersion_env%maxci, zc, za, &
546 cnumfix(katom), cnumfix(iatom), dispersion_env%k3, cc6ca, dcc6cac, dcc6caa)
547 ELSE
548 CALL getc6(maxc, max_elem, dispersion_env%c6ab, dispersion_env%maxci, za, zb, &
549 cnumbers(iatom), cnumbers(jatom), dispersion_env%k3, cc6ab, dcc6aba, dcc6abb)
550 CALL getc6(maxc, max_elem, dispersion_env%c6ab, dispersion_env%maxci, zb, zc, &
551 cnumbers(jatom), cnumbers(katom), dispersion_env%k3, cc6bc, dcc6bcb, dcc6bcc)
552 CALL getc6(maxc, max_elem, dispersion_env%c6ab, dispersion_env%maxci, zc, za, &
553 cnumbers(katom), cnumbers(iatom), dispersion_env%k3, cc6ca, dcc6cac, dcc6caa)
554 END IF
555 c9 = -sqrt(cc6ab*cc6bc*cc6ca)
556 rabc = r2abc**(1._dp/6._dp)
557 r0 = (dispersion_env%r0ab(za, zb)*dispersion_env%r0ab(zb, zc)* &
558 dispersion_env%r0ab(zc, za))**(1._dp/3._dp)
559 ! bug fixed 3.10.2017
560 ! correct value from alp6=14 to 16 as used in original paper
561 CALL damping_d3(rabc, r0, 4._dp/3._dp, 16.0_dp, rcut, fdabc, dfdabc)
562 s1 = r2ab + r2bc - r2ca
563 s2 = r2ab + r2ca - r2bc
564 s3 = r2ca + r2bc - r2ab
565 ang = 0.375_dp*s1*s2*s3/r2abc + 1.0_dp
566
567 e9 = s9*fac*fdabc*c9*ang/r2abc**1.50d0
568 evdw = evdw - e9
569 e9tot = e9tot - e9
570 IF (atenergy) THEN
571 atener(iatom) = atener(iatom) - e9/3._dp
572 atener(jatom) = atener(jatom) - e9/3._dp
573 atener(katom) = atener(katom) - e9/3._dp
574 END IF
575 IF (atex) THEN
576 atevdw(iatom) = atevdw(iatom) - e9/3._dp
577 atevdw(jatom) = atevdw(jatom) - e9/3._dp
578 atevdw(katom) = atevdw(katom) - e9/3._dp
579 END IF
580
581 IF (calculate_forces) THEN
582 rab = rb - ra; rbc = rc - rb; rca = ra - rc
583 de91 = s9*fac*dfdabc*c9*ang/r2abc**1.50d0
584 de91 = -de91/3._dp*rabc + 3._dp*e9
585 dea = s9*fac*fdabc*c9/r2abc**2.50d0*0.75_dp
586 fdij(:) = de91*rab(:)/r2ab
587 fdij(:) = fdij(:) + dea*s1*s2*s3*rab(:)/r2ab
588 fdij(:) = fdij(:) - dea*(s2*s3 + s1*s3 - s1*s2)*rab(:)
589 force(ikind)%dispersion(:, atom_a) = force(ikind)%dispersion(:, atom_a) - fdij(:)
590 force(jkind)%dispersion(:, atom_b) = force(jkind)%dispersion(:, atom_b) + fdij(:)
591 IF (use_virial) THEN
592 CALL virial_pair_force(pv_virial_thread, -1._dp, fdij, rab)
593 END IF
594 fdij(:) = de91*rbc(:)/r2bc
595 fdij(:) = fdij(:) + dea*s1*s2*s3*rbc(:)/r2bc
596 fdij(:) = fdij(:) - dea*(s2*s3 - s1*s3 + s1*s2)*rbc(:)
597 force(jkind)%dispersion(:, atom_b) = force(jkind)%dispersion(:, atom_b) - fdij(:)
598 force(kkind)%dispersion(:, atom_c) = force(kkind)%dispersion(:, atom_c) + fdij(:)
599 IF (use_virial) THEN
600 CALL virial_pair_force(pv_virial_thread, -1._dp, fdij, rbc)
601 END IF
602 fdij(:) = de91*rca(:)/r2ca
603 fdij(:) = fdij(:) + dea*s1*s2*s3*rca(:)/r2ca
604 fdij(:) = fdij(:) - dea*(-s2*s3 + s1*s3 + s1*s2)*rca(:)
605 force(kkind)%dispersion(:, atom_c) = force(kkind)%dispersion(:, atom_c) - fdij(:)
606 force(ikind)%dispersion(:, atom_a) = force(ikind)%dispersion(:, atom_a) + fdij(:)
607 IF (use_virial) THEN
608 CALL virial_pair_force(pv_virial_thread, -1._dp, fdij, rca)
609 END IF
610
611 IF (.NOT. dispersion_env%c9cnst) THEN
612 ! forces from the r-dependence of the coordination numbers
613 ! atomic stress not implemented
614
615 de91 = 0.5_dp*e9/cc6ab
616 de921 = de91*dcc6aba
617 de922 = de91*dcc6abb
618 DO i = 1, dcnum(iatom)%neighbors
619 latom = dcnum(iatom)%nlist(i)
620 lkind = kind_of(latom)
621 rik(1) = dcnum(iatom)%rik(1, i)
622 rik(2) = dcnum(iatom)%rik(2, i)
623 rik(3) = dcnum(iatom)%rik(3, i)
624 drk = sqrt(rik(1)*rik(1) + rik(2)*rik(2) + rik(3)*rik(3))
625 fdik(:) = -de921*dcnum(iatom)%dvals(i)*rik(:)/drk
626 atom_d = atom_of_kind(latom)
627 force(ikind)%dispersion(:, atom_a) = force(ikind)%dispersion(:, atom_a) - fdik(:)
628 force(lkind)%dispersion(:, atom_d) = force(lkind)%dispersion(:, atom_d) + fdik(:)
629 IF (use_virial) THEN
630 CALL virial_pair_force(pv_virial_thread, -1._dp, fdik, rik)
631 END IF
632 END DO
633 DO i = 1, dcnum(jatom)%neighbors
634 latom = dcnum(jatom)%nlist(i)
635 lkind = kind_of(latom)
636 rik(1) = dcnum(jatom)%rik(1, i)
637 rik(2) = dcnum(jatom)%rik(2, i)
638 rik(3) = dcnum(jatom)%rik(3, i)
639 drk = sqrt(rik(1)*rik(1) + rik(2)*rik(2) + rik(3)*rik(3))
640 fdik(:) = -de922*dcnum(jatom)%dvals(i)*rik(:)/drk
641 atom_d = atom_of_kind(latom)
642 force(jkind)%dispersion(:, atom_b) = force(jkind)%dispersion(:, atom_b) - fdik(:)
643 force(lkind)%dispersion(:, atom_d) = force(lkind)%dispersion(:, atom_d) + fdik(:)
644 IF (use_virial) THEN
645 CALL virial_pair_force(pv_virial_thread, -1._dp, fdik, rik)
646 END IF
647 END DO
648
649 de91 = 0.5_dp*e9/cc6bc
650 de921 = de91*dcc6bcb
651 de922 = de91*dcc6bcc
652 DO i = 1, dcnum(jatom)%neighbors
653 latom = dcnum(jatom)%nlist(i)
654 lkind = kind_of(latom)
655 rik(1) = dcnum(jatom)%rik(1, i)
656 rik(2) = dcnum(jatom)%rik(2, i)
657 rik(3) = dcnum(jatom)%rik(3, i)
658 drk = sqrt(rik(1)*rik(1) + rik(2)*rik(2) + rik(3)*rik(3))
659 fdik(:) = -de921*dcnum(jatom)%dvals(i)*rik(:)/drk
660 atom_d = atom_of_kind(latom)
661 force(jkind)%dispersion(:, atom_b) = force(jkind)%dispersion(:, atom_b) - fdik(:)
662 force(lkind)%dispersion(:, atom_d) = force(lkind)%dispersion(:, atom_d) + fdik(:)
663 IF (use_virial) THEN
664 CALL virial_pair_force(pv_virial_thread, -1._dp, fdik, rik)
665 END IF
666 END DO
667 DO i = 1, dcnum(katom)%neighbors
668 latom = dcnum(katom)%nlist(i)
669 lkind = kind_of(latom)
670 rik(1) = dcnum(katom)%rik(1, i)
671 rik(2) = dcnum(katom)%rik(2, i)
672 rik(3) = dcnum(katom)%rik(3, i)
673 drk = sqrt(rik(1)*rik(1) + rik(2)*rik(2) + rik(3)*rik(3))
674 fdik(:) = -de922*dcnum(katom)%dvals(i)*rik(:)/drk
675 atom_d = atom_of_kind(latom)
676 force(kkind)%dispersion(:, atom_c) = force(kkind)%dispersion(:, atom_c) - fdik(:)
677 force(lkind)%dispersion(:, atom_d) = force(lkind)%dispersion(:, atom_d) + fdik(:)
678 IF (use_virial) THEN
679 CALL virial_pair_force(pv_virial_thread, -1._dp, fdik, rik)
680 END IF
681 END DO
682
683 de91 = 0.5_dp*e9/cc6ca
684 de921 = de91*dcc6cac
685 de922 = de91*dcc6caa
686 DO i = 1, dcnum(katom)%neighbors
687 latom = dcnum(katom)%nlist(i)
688 lkind = kind_of(latom)
689 rik(1) = dcnum(katom)%rik(1, i)
690 rik(2) = dcnum(katom)%rik(2, i)
691 rik(3) = dcnum(katom)%rik(3, i)
692 drk = sqrt(rik(1)*rik(1) + rik(2)*rik(2) + rik(3)*rik(3))
693 fdik(:) = -de921*dcnum(katom)%dvals(i)*rik(:)/drk
694 atom_d = atom_of_kind(latom)
695 force(kkind)%dispersion(:, atom_c) = force(kkind)%dispersion(:, atom_c) - fdik(:)
696 force(lkind)%dispersion(:, atom_d) = force(lkind)%dispersion(:, atom_d) + fdik(:)
697 IF (use_virial) THEN
698 CALL virial_pair_force(pv_virial_thread, -1._dp, fdik, rik)
699 END IF
700 END DO
701 DO i = 1, dcnum(iatom)%neighbors
702 latom = dcnum(iatom)%nlist(i)
703 lkind = kind_of(latom)
704 rik(1) = dcnum(iatom)%rik(1, i)
705 rik(2) = dcnum(iatom)%rik(2, i)
706 rik(3) = dcnum(iatom)%rik(3, i)
707 drk = sqrt(rik(1)*rik(1) + rik(2)*rik(2) + rik(3)*rik(3))
708 fdik(:) = -de922*dcnum(iatom)%dvals(i)*rik(:)/drk
709 atom_d = atom_of_kind(latom)
710 force(ikind)%dispersion(:, atom_a) = force(ikind)%dispersion(:, atom_a) - fdik(:)
711 force(lkind)%dispersion(:, atom_d) = force(lkind)%dispersion(:, atom_d) + fdik(:)
712 IF (use_virial) THEN
713 CALL virial_pair_force(pv_virial_thread, -1._dp, fdik, rik)
714 END IF
715 END DO
716 END IF
717
718 END IF
719
720 END IF
721 END DO
722 END DO
723 END DO
724 END DO
725
726 END IF
727 END IF
728 END IF
729 END DO
730
731 virial%pv_virial = virial%pv_virial + pv_virial_thread
732
733 CALL neighbor_list_iterator_release(nl_iterator)
734
735 elrc6 = 0._dp
736 elrc8 = 0._dp
737 elrc9 = 0._dp
738 ! Long range correction (atomic contributions not implemented)
739 IF (dispersion_env%lrc) THEN
740 ALLOCATE (cnkind(nkind))
741 cnkind = 0._dp
742 ! first use the default values
743 DO ikind = 1, nkind
744 CALL get_atomic_kind(atomic_kind_set(ikind), z=za)
745 cnkind(ikind) = dispersion_env%cn(za)
746 END DO
747 ! now check for changes from default
748 IF (ASSOCIATED(dispersion_env%cnkind)) THEN
749 DO i = 1, SIZE(dispersion_env%cnkind)
750 ikind = dispersion_env%cnkind(i)%kind
751 cnkind(ikind) = dispersion_env%cnkind(i)%cnum
752 END DO
753 END IF
754 DO ikind = 1, nkind
755 CALL get_atomic_kind(atomic_kind_set(ikind), natom=na, z=za)
756 CALL get_qs_kind(qs_kind_set(ikind), dispersion=disp_a, ghost=ghost_a, floating=floating_a)
757 IF (.NOT. disp_a%defined .OR. ghost_a .OR. floating_a) cycle
758 DO jkind = 1, nkind
759 CALL get_atomic_kind(atomic_kind_set(jkind), natom=nb, z=zb)
760 CALL get_qs_kind(qs_kind_set(jkind), dispersion=disp_b, ghost=ghost_b, floating=floating_b)
761 IF (.NOT. disp_b%defined .OR. ghost_b .OR. floating_b) cycle
762 IF (dispersion_env%nd3_exclude_pair > 0) THEN
763 CALL exclude_d3_kind_pair(dispersion_env%d3_exclude_pair, ikind, jkind, &
764 exclude=exclude_pair)
765 IF (exclude_pair) cycle
766 END IF
767 CALL getc6(maxc, max_elem, dispersion_env%c6ab, dispersion_env%maxci, za, zb, &
768 cnkind(ikind), cnkind(jkind), dispersion_env%k3, cc6ab, dcc6aba, dcc6abb)
769 elrc6 = elrc6 - s6*twopi*real(na*nb, kind=dp)*cc6ab/(3._dp*rcut**3*cell%deth)
770 c8 = 3.0d0*cc6ab*dispersion_env%r2r4(za)*dispersion_env%r2r4(zb)
771 elrc8 = elrc8 - s8*twopi*real(na*nb, kind=dp)*c8/(5._dp*rcut**5*cell%deth)
772 IF (dispersion_env%doabc) THEN
773 DO kkind = 1, nkind
774 CALL get_atomic_kind(atomic_kind_set(kkind), natom=nc, z=zc)
775 CALL get_qs_kind(qs_kind_set(kkind), dispersion=disp_c, ghost=ghost_c, floating=floating_c)
776 IF (.NOT. disp_c%defined .OR. ghost_c .OR. floating_c) cycle
777 IF (dispersion_env%nd3_exclude_pair > 0) THEN
778 CALL exclude_d3_kind_pair(dispersion_env%d3_exclude_pair, ikind, jkind, kkind, &
779 exclude_pair)
780 IF (exclude_pair) cycle
781 END IF
782 CALL getc6(maxc, max_elem, dispersion_env%c6ab, dispersion_env%maxci, za, zb, &
783 cnkind(ikind), cnkind(jkind), dispersion_env%k3, cc6ab, dcc6aba, dcc6abb)
784 CALL getc6(maxc, max_elem, dispersion_env%c6ab, dispersion_env%maxci, zc, za, &
785 cnkind(kkind), cnkind(ikind), dispersion_env%k3, cc6ca, dcc6aba, dcc6abb)
786 CALL getc6(maxc, max_elem, dispersion_env%c6ab, dispersion_env%maxci, zb, zc, &
787 cnkind(jkind), cnkind(kkind), dispersion_env%k3, cc6bc, dcc6aba, dcc6abb)
788 c9 = -sqrt(cc6ab*cc6bc*cc6ca)
789 elrc9 = elrc9 - s9*64._dp*twopi*real(na*nb*nc, kind=dp)*c9/(6._dp*rcut**3*cell%deth**2)
790 END DO
791 END IF
792 END DO
793 END DO
794 IF (use_virial) THEN
795 IF (para_env%is_source()) THEN
796 DO i = 1, 3
797 virial%pv_virial(i, i) = virial%pv_virial(i, i) + (elrc6 + elrc8 + 2._dp*elrc9)
798 END DO
799 END IF
800 END IF
801 DEALLOCATE (cnkind)
802 END IF
803
804 DEALLOCATE (cnumbers)
805 IF (dispersion_env%doabc .AND. dispersion_env%c9cnst) THEN
806 DEALLOCATE (cnumfix)
807 END IF
808 IF (calculate_forces .OR. debugall) THEN
809 DO iatom = 1, natom
810 DEALLOCATE (dcnum(iatom)%nlist, dcnum(iatom)%dvals, dcnum(iatom)%rik)
811 END DO
812 DEALLOCATE (dcnum)
813 ELSE
814 DEALLOCATE (dcnum)
815 END IF
816
817 ! set dispersion energy
818 IF (para_env%is_source()) THEN
819 evdw = evdw + (elrc6 + elrc8 + elrc9)
820 END IF
821
822 CALL para_env%sum(e6tot)
823 CALL para_env%sum(e8tot)
824 CALL para_env%sum(e9tot)
825 CALL para_env%sum(nab)
826 CALL para_env%sum(nabc)
827 e6tot = e6tot + elrc6
828 e8tot = e8tot + elrc8
829 e9tot = e9tot + elrc9
830 IF (unit_nr > 0) THEN
831 WRITE (unit_nr, "(A,F20.0)") " E6 vdW terms :", nab
832 WRITE (unit_nr, *) " E6 vdW energy [au/kcal] :", e6tot, e6tot*kcalmol
833 WRITE (unit_nr, *) " E8 vdW energy [au/kcal] :", e8tot, e8tot*kcalmol
834 WRITE (unit_nr, *) " %E8 on total vdW energy :", e8tot/evdw*100._dp
835 WRITE (unit_nr, "(A,F20.0)") " E9 vdW terms :", nabc
836 WRITE (unit_nr, *) " E9 vdW energy [au/kcal] :", e9tot, e9tot*kcalmol
837 WRITE (unit_nr, *) " %E9 on total vdW energy :", e9tot/evdw*100._dp
838 IF (dispersion_env%lrc) THEN
839 WRITE (unit_nr, *) " E LRC C6 [au/kcal] :", elrc6, elrc6*kcalmol
840 WRITE (unit_nr, *) " E LRC C8 [au/kcal] :", elrc8, elrc8*kcalmol
841 WRITE (unit_nr, *) " E LRC C9 [au/kcal] :", elrc9, elrc9*kcalmol
842 END IF
843 END IF
844
845 DEALLOCATE (dodisp, exclude, atomnumber, rcpbc, radd2, c6d2)
846
847 IF (domol) THEN
848 DEALLOCATE (atom2mol)
849 END IF
850
851 CALL timestop(handle)
852
854
855! **************************************************************************************************
856!> \brief ...
857!> \param c6ab ...
858!> \param maxci ...
859!> \param filename ...
860!> \param para_env ...
861! **************************************************************************************************
862 SUBROUTINE dftd3_c6_param(c6ab, maxci, filename, para_env)
863
864 REAL(kind=dp), DIMENSION(:, :, :, :, :) :: c6ab
865 INTEGER, DIMENSION(:) :: maxci
866 CHARACTER(LEN=*) :: filename
867 TYPE(mp_para_env_type), POINTER :: para_env
868
869 INTEGER :: funit, iadr, iat, jadr, jat, kk, nl, &
870 nlines, nn
871 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: pars
872
873 IF (para_env%is_source()) THEN
874 ! Read the DFT-D3 C6AB parameters from file "filename"
875 CALL open_file(file_name=filename, unit_number=funit, file_form="FORMATTED")
876 READ (funit, *) nl, nlines
877 END IF
878 CALL para_env%bcast(nl)
879 CALL para_env%bcast(nlines)
880 ALLOCATE (pars(nl))
881 IF (para_env%is_source()) THEN
882 READ (funit, *) pars(1:nl)
883 CALL close_file(unit_number=funit)
884 END IF
885 CALL para_env%bcast(pars)
886
887 ! Store C6AB coefficients in an array
888 c6ab = -1._dp
889 maxci = 0
890 kk = 1
891 DO nn = 1, nlines
892 iat = nint(pars(kk + 1))
893 jat = nint(pars(kk + 2))
894 CALL limit(iat, jat, iadr, jadr)
895 maxci(iat) = max(maxci(iat), iadr)
896 maxci(jat) = max(maxci(jat), jadr)
897 c6ab(iat, jat, iadr, jadr, 1) = pars(kk)
898 c6ab(iat, jat, iadr, jadr, 2) = pars(kk + 3)
899 c6ab(iat, jat, iadr, jadr, 3) = pars(kk + 4)
900
901 c6ab(jat, iat, jadr, iadr, 1) = pars(kk)
902 c6ab(jat, iat, jadr, iadr, 2) = pars(kk + 4)
903 c6ab(jat, iat, jadr, iadr, 3) = pars(kk + 3)
904 kk = (nn*5) + 1
905 END DO
906
907 DEALLOCATE (pars)
908
909 END SUBROUTINE dftd3_c6_param
910
911! **************************************************************************************************
912!> \brief ...
913!> \param iat ...
914!> \param jat ...
915!> \param iadr ...
916!> \param jadr ...
917! **************************************************************************************************
918 SUBROUTINE limit(iat, jat, iadr, jadr)
919 INTEGER :: iat, jat, iadr, jadr
920
921 INTEGER :: i
922
923 iadr = 1
924 jadr = 1
925 i = 100
926 DO WHILE (iat .GT. 100)
927 iat = iat - 100
928 iadr = iadr + 1
929 END DO
930
931 i = 100
932 DO WHILE (jat .GT. 100)
933 jat = jat - 100
934 jadr = jadr + 1
935 END DO
936 END SUBROUTINE limit
937
938! **************************************************************************************************
939!> \brief ...
940!> \param rab ...
941!> \param rcutab ...
942!> \param srn ...
943!> \param alpn ...
944!> \param rcut ...
945!> \param fdab ...
946!> \param dfdab ...
947! **************************************************************************************************
948 SUBROUTINE damping_d3(rab, rcutab, srn, alpn, rcut, fdab, dfdab)
949
950 REAL(kind=dp), INTENT(IN) :: rab, rcutab, srn, alpn, rcut
951 REAL(kind=dp), INTENT(OUT) :: fdab, dfdab
952
953 REAL(kind=dp) :: a, b, c, d, dd, dfab, dfcc, dz, fab, &
954 fcc, rl, rr, ru, z, zz
955
956 rl = rcut - 1._dp
957 ru = rcut
958 IF (rab >= ru) THEN
959 fcc = 0._dp
960 dfcc = 0._dp
961 ELSEIF (rab <= rl) THEN
962 fcc = 1._dp
963 dfcc = 0._dp
964 ELSE
965 z = rab*rab - rl*rl
966 dz = 2._dp*rab
967 zz = z*z*z
968 d = ru*ru - rl*rl
969 dd = d*d*d
970 a = -10._dp/dd
971 b = 15._dp/(dd*d)
972 c = -6._dp/(dd*d*d)
973 fcc = 1._dp + zz*(a + b*z + c*z*z)
974 dfcc = zz*dz/z*(3._dp*a + 4._dp*b*z + 5._dp*c*z*z)
975 END IF
976
977 rr = 6._dp*(rab/(srn*rcutab))**(-alpn)
978 fab = 1._dp/(1._dp + rr)
979 dfab = fab*fab*rr*alpn/rab
980 fdab = fab*fcc
981 dfdab = dfab*fcc + fab*dfcc
982
983 END SUBROUTINE damping_d3
984
985! **************************************************************************************************
986!> \brief ...
987!> \param maxc ...
988!> \param max_elem ...
989!> \param c6ab ...
990!> \param mxc ...
991!> \param iat ...
992!> \param jat ...
993!> \param nci ...
994!> \param ncj ...
995!> \param k3 ...
996!> \param c6 ...
997!> \param dc6a ...
998!> \param dc6b ...
999! **************************************************************************************************
1000 SUBROUTINE getc6(maxc, max_elem, c6ab, mxc, iat, jat, nci, ncj, k3, c6, dc6a, dc6b)
1001
1002 INTEGER, INTENT(IN) :: maxc, max_elem
1003 REAL(kind=dp), INTENT(IN) :: c6ab(max_elem, max_elem, maxc, maxc, 3)
1004 INTEGER, INTENT(IN) :: mxc(max_elem), iat, jat
1005 REAL(kind=dp), INTENT(IN) :: nci, ncj, k3
1006 REAL(kind=dp), INTENT(OUT) :: c6, dc6a, dc6b
1007
1008 INTEGER :: i, j
1009 REAL(kind=dp) :: c6mem, cn1, cn2, csum, dtmpa, dtmpb, &
1010 dwa, dwb, dza, dzb, r, rsave, rsum, &
1011 tmp1
1012
1013! the exponential is sensitive to numerics
1014! when nci or ncj is much larger than cn1/cn2
1015
1016 c6mem = -1.0e+99_dp
1017 rsave = 1.0e+99_dp
1018 rsum = 0.0_dp
1019 csum = 0.0_dp
1020 dza = 0.0_dp
1021 dzb = 0.0_dp
1022 dwa = 0.0_dp
1023 dwb = 0.0_dp
1024 c6 = 0.0_dp
1025 DO i = 1, mxc(iat)
1026 DO j = 1, mxc(jat)
1027 c6 = c6ab(iat, jat, i, j, 1)
1028 IF (c6 > 0.0_dp) THEN
1029 cn1 = c6ab(iat, jat, i, j, 2)
1030 cn2 = c6ab(iat, jat, i, j, 3)
1031 ! distance
1032 r = (cn1 - nci)**2 + (cn2 - ncj)**2
1033 IF (r < rsave) THEN
1034 rsave = r
1035 c6mem = c6
1036 END IF
1037 tmp1 = exp(k3*r)
1038 dtmpa = -2.0_dp*k3*(cn1 - nci)*tmp1
1039 dtmpb = -2.0_dp*k3*(cn2 - ncj)*tmp1
1040 rsum = rsum + tmp1
1041 csum = csum + tmp1*c6
1042 dza = dza + dtmpa*c6
1043 dwa = dwa + dtmpa
1044 dzb = dzb + dtmpb*c6
1045 dwb = dwb + dtmpb
1046 END IF
1047 END DO
1048 END DO
1049
1050 IF (c6 == 0.0_dp) c6mem = 0.0_dp
1051
1052 IF (rsum > 1.0e-66_dp) THEN
1053 c6 = csum/rsum
1054 dc6a = (dza - c6*dwa)/rsum
1055 dc6b = (dzb - c6*dwb)/rsum
1056 ELSE
1057 c6 = c6mem
1058 dc6a = 0._dp
1059 dc6b = 0._dp
1060 END IF
1061
1062 END SUBROUTINE getc6
1063
1064END 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:195
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:252
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:308
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:119
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, 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, 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, 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, ecoul_1c, rho0_s_rs, rho0_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)
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, 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, 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:55
stores all the informations relevant to an mpi environment
Provides all information about a quickstep kind.