(git:495eafe)
Loading...
Searching...
No Matches
cp_ddapc_forces.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 Density Derived atomic point charges from a QM calculation
10!> (see J. Chem. Phys. Vol. 103 pp. 7422-7428)
11!> \par History
12!> 08.2005 created [tlaino]
13!> \author Teodoro Laino
14! **************************************************************************************************
16
19 USE cell_types, ONLY: cell_type
27 USE kinds, ONLY: dp
28 USE mathconstants, ONLY: fourpi,&
29 pi,&
30 rootpi,&
31 twopi
35 USE pw_types, ONLY: pw_r3d_rs_type
41!NB for reducing results of calculations that use dq, which is now spread over nodes
42#include "./base/base_uses.f90"
43
44 IMPLICIT NONE
45 PRIVATE
46
47 LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .true.
48 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'cp_ddapc_forces'
49 PUBLIC :: ewald_ddapc_force, &
54
55CONTAINS
56
57! **************************************************************************************************
58!> \brief Evaluates the Ewald term E2 and E3 energy term for the decoupling/coupling
59!> of periodic images
60!> \param qs_env ...
61!> \param coeff ...
62!> \param apply_qmmm_periodic ...
63!> \param factor ...
64!> \param multipole_section ...
65!> \param cell ...
66!> \param particle_set ...
67!> \param radii ...
68!> \param dq ...
69!> \param charges ...
70!> \par History
71!> 08.2005 created [tlaino]
72!> \author Teodoro Laino
73! **************************************************************************************************
74 RECURSIVE SUBROUTINE ewald_ddapc_force(qs_env, coeff, apply_qmmm_periodic, &
75 factor, multipole_section, cell, particle_set, radii, dq, charges)
76 TYPE(qs_environment_type), POINTER :: qs_env
77 TYPE(pw_r3d_rs_type), INTENT(IN), POINTER :: coeff
78 LOGICAL, INTENT(IN) :: apply_qmmm_periodic
79 REAL(kind=dp), INTENT(IN) :: factor
80 TYPE(section_vals_type), POINTER :: multipole_section
81 TYPE(cell_type), POINTER :: cell
82 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
83 REAL(kind=dp), DIMENSION(:), POINTER :: radii
84 REAL(kind=dp), DIMENSION(:, :, :), OPTIONAL, &
85 POINTER :: dq
86 REAL(kind=dp), DIMENSION(:), OPTIONAL, POINTER :: charges
87
88 CHARACTER(len=*), PARAMETER :: routinen = 'ewald_ddapc_force'
89
90 INTEGER :: handle, idim, ip1, ip2, iparticle1, &
91 iparticle2, k1, k2, k3, n_rep, r1, r2, &
92 r3
93 INTEGER, DIMENSION(3) :: gmax, image_cell, rmax, rmin
94 LOGICAL :: analyt
95 REAL(kind=dp) :: alpha, eps, fac, frac_radius, fs, &
96 galpha, gsq, gsqi, ij_fac, q1t, q2t, &
97 r, r2tmp, rcut, rcut2, t1, t2, tol, &
98 tol1
99 REAL(kind=dp), DIMENSION(3) :: drvec, g_index, gvec, ra, rvec, svec
100 REAL(kind=dp), DIMENSION(:, :), POINTER :: d_el, m
101 TYPE(mp_para_env_type), POINTER :: para_env
102
103 NULLIFY (d_el, m, para_env)
104 CALL timeset(routinen, handle)
105 CALL get_qs_env(qs_env, para_env=para_env)
106 cpassert(PRESENT(charges))
107 cpassert(ASSOCIATED(radii))
108 rcut = min(norm2(cell%hmat(:, 1)), norm2(cell%hmat(:, 2)), norm2(cell%hmat(:, 3)))/2.0_dp
109 CALL section_vals_val_get(multipole_section, "RCUT", n_rep_val=n_rep)
110 IF (n_rep == 1) CALL section_vals_val_get(multipole_section, "RCUT", r_val=rcut)
111 CALL section_vals_val_get(multipole_section, "EWALD_PRECISION", r_val=eps)
112 CALL section_vals_val_get(multipole_section, "ANALYTICAL_GTERM", l_val=analyt)
113 ! The spline interpolation path is only valid for orthorhombic grids.
114 analyt = analyt .OR. .NOT. cell%orthorhombic .OR. .NOT. ASSOCIATED(coeff)
115 rcut2 = rcut**2
116 !
117 ! Setting-up parameters for Ewald summation
118 !
119 eps = min(abs(eps), 0.5_dp)
120 tol = sqrt(abs(log(eps*rcut)))
121 alpha = sqrt(abs(log(eps*rcut*tol)))/rcut
122 galpha = 1.0_dp/(4.0_dp*alpha*alpha)
123 tol1 = sqrt(-log(eps*rcut*(2.0_dp*tol*alpha)**2))
124 IF (cell%orthorhombic) THEN
125 DO idim = 1, 3
126 gmax(idim) = nint(0.25_dp + cell%hmat(idim, idim)*alpha*tol1/pi)
127 END DO
128 ELSE
129 DO idim = 1, 3
130 gmax(idim) = ceiling(alpha*tol1*norm2(cell%hmat(:, idim))/pi)
131 END DO
132 END IF
133
134 ALLOCATE (d_el(3, SIZE(particle_set)))
135 d_el = 0.0_dp
136 fac = 1.e0_dp/cell%deth
137 !
138 DO iparticle1 = 1, SIZE(particle_set)
139 !NB parallelization
140 IF (mod(iparticle1, para_env%num_pe) /= para_env%mepos) cycle
141 ip1 = (iparticle1 - 1)*SIZE(radii)
142 q1t = sum(charges(ip1 + 1:ip1 + SIZE(radii)))
143 DO iparticle2 = 1, iparticle1
144 ij_fac = 1.0_dp
145 IF (iparticle1 == iparticle2) ij_fac = 0.5_dp
146
147 ip2 = (iparticle2 - 1)*SIZE(radii)
148 q2t = sum(charges(ip2 + 1:ip2 + SIZE(radii)))
149 !
150 ! Real-Space Contribution
151 !
152 rvec = particle_set(iparticle1)%r - particle_set(iparticle2)%r
153 IF (iparticle1 /= iparticle2) THEN
154 ra = rvec
155 r2tmp = dot_product(ra, ra)
156 IF (r2tmp <= rcut2) THEN
157 r = sqrt(r2tmp)
158 t1 = erfc(alpha*r)/r
159 drvec = ra/r*q1t*q2t*factor
160 t2 = -2.0_dp*alpha*exp(-alpha*alpha*r*r)/(r*rootpi) - t1/r
161 d_el(1:3, iparticle1) = d_el(1:3, iparticle1) - t2*drvec
162 d_el(1:3, iparticle2) = d_el(1:3, iparticle2) + t2*drvec
163 END IF
164 END IF
165 svec = matmul(cell%h_inv, rvec)
166 DO idim = 1, 3
167 frac_radius = rcut*norm2(cell%h_inv(idim, :))
168 rmin(idim) = floor(-svec(idim) - frac_radius)
169 rmax(idim) = ceiling(-svec(idim) + frac_radius)
170 END DO
171 DO r1 = rmin(1), rmax(1)
172 DO r2 = rmin(2), rmax(2)
173 DO r3 = rmin(3), rmax(3)
174 IF ((r1 == 0) .AND. (r2 == 0) .AND. (r3 == 0)) cycle
175 image_cell = [r1, r2, r3]
176 ra = rvec + matmul(cell%hmat, real(image_cell, kind=dp))
177 r2tmp = dot_product(ra, ra)
178 IF (r2tmp <= rcut2) THEN
179 r = sqrt(r2tmp)
180 t1 = erfc(alpha*r)/r
181 drvec = ra/r*q1t*q2t*factor*ij_fac
182 t2 = -2.0_dp*alpha*exp(-alpha*alpha*r*r)/(r*rootpi) - t1/r
183 d_el(1, iparticle1) = d_el(1, iparticle1) - t2*drvec(1)
184 d_el(2, iparticle1) = d_el(2, iparticle1) - t2*drvec(2)
185 d_el(3, iparticle1) = d_el(3, iparticle1) - t2*drvec(3)
186 d_el(1, iparticle2) = d_el(1, iparticle2) + t2*drvec(1)
187 d_el(2, iparticle2) = d_el(2, iparticle2) + t2*drvec(2)
188 d_el(3, iparticle2) = d_el(3, iparticle2) + t2*drvec(3)
189 END IF
190 END DO
191 END DO
192 END DO
193 !
194 ! G-space Contribution
195 !
196 IF (analyt) THEN
197 DO k1 = 0, gmax(1)
198 DO k2 = -gmax(2), gmax(2)
199 DO k3 = -gmax(3), gmax(3)
200 IF (k1 == 0 .AND. k2 == 0 .AND. k3 == 0) cycle
201 fs = 2.0_dp; IF (k1 == 0) fs = 1.0_dp
202 g_index = [real(k1, kind=dp), real(k2, kind=dp), real(k3, kind=dp)]
203 gvec = twopi*matmul(transpose(cell%h_inv), g_index)
204 gsq = dot_product(gvec, gvec)
205 gsqi = fs/gsq
206 t1 = fac*gsqi*exp(-galpha*gsq)
207 t2 = -sin(dot_product(gvec, rvec))*t1*q1t*q2t*factor*fourpi
208 d_el(1:3, iparticle1) = d_el(1:3, iparticle1) - t2*gvec
209 d_el(1:3, iparticle2) = d_el(1:3, iparticle2) + t2*gvec
210 END DO
211 END DO
212 END DO
213 ELSE
214 gvec = eval_d_interp_spl3_pbc(rvec, coeff)*q1t*q2t*factor*fourpi
215 d_el(1:3, iparticle1) = d_el(1:3, iparticle1) - gvec
216 d_el(1:3, iparticle2) = d_el(1:3, iparticle2) + gvec
217 END IF
218 IF (iparticle1 /= iparticle2) THEN
219 ra = rvec
220 r = sqrt(dot_product(ra, ra))
221 t2 = -1.0_dp/(r*r)*factor
222 drvec = ra/r*q1t*q2t
223 d_el(1:3, iparticle1) = d_el(1:3, iparticle1) + t2*drvec
224 d_el(1:3, iparticle2) = d_el(1:3, iparticle2) - t2*drvec
225 END IF
226 END DO ! iparticle2
227 END DO ! iparticle1
228 !NB parallelization
229 CALL para_env%sum(d_el)
230 m => qs_env%cp_ddapc_env%Md
231 IF (apply_qmmm_periodic) m => qs_env%cp_ddapc_env%Mr
232 CALL cp_decpl_ddapc_forces(qs_env, m, charges, dq, d_el, particle_set)
233 DEALLOCATE (d_el)
234 CALL timestop(handle)
235 END SUBROUTINE ewald_ddapc_force
236
237! **************************************************************************************************
238!> \brief Evaluation of the pulay forces due to the fitted charge density
239!> \param qs_env ...
240!> \param M ...
241!> \param charges ...
242!> \param dq ...
243!> \param d_el ...
244!> \param particle_set ...
245!> \par History
246!> 08.2005 created [tlaino]
247!> \author Teodoro Laino
248! **************************************************************************************************
249 SUBROUTINE cp_decpl_ddapc_forces(qs_env, M, charges, dq, d_el, particle_set)
250 TYPE(qs_environment_type), POINTER :: qs_env
251 REAL(kind=dp), DIMENSION(:, :), POINTER :: m
252 REAL(kind=dp), DIMENSION(:), POINTER :: charges
253 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: dq
254 REAL(kind=dp), DIMENSION(:, :), POINTER :: d_el
255 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
256
257 CHARACTER(len=*), PARAMETER :: routinen = 'cp_decpl_ddapc_forces'
258
259 INTEGER :: handle, i, iatom, ikind, j, k, natom
260 INTEGER, ALLOCATABLE, DIMENSION(:) :: atom_of_kind, kind_of
261 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: uv
262 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: chf
263 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
264 TYPE(mp_para_env_type), POINTER :: para_env
265 TYPE(qs_force_type), DIMENSION(:), POINTER :: force
266
267 NULLIFY (para_env)
268 CALL timeset(routinen, handle)
269 natom = SIZE(particle_set)
270 CALL get_qs_env(qs_env=qs_env, &
271 atomic_kind_set=atomic_kind_set, &
272 para_env=para_env, &
273 force=force)
274 ALLOCATE (chf(3, natom))
275 CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, &
276 atom_of_kind=atom_of_kind, &
277 kind_of=kind_of)
278
279 ALLOCATE (uv(SIZE(m, 1)))
280 uv(:) = matmul(m, charges)
281 DO k = 1, natom
282 DO j = 1, 3
283 chf(j, k) = dot_product(uv, dq(:, k, j))
284 END DO
285 END DO
286 !NB now that get_ddapc returns dq that's spread over nodes, must reduce chf here
287 CALL para_env%sum(chf)
288 DO iatom = 1, natom
289 ikind = kind_of(iatom)
290 i = atom_of_kind(iatom)
291 force(ikind)%ch_pulay(1:3, i) = force(ikind)%ch_pulay(1:3, i) + chf(1:3, iatom) + d_el(1:3, iatom)
292 END DO
293 DEALLOCATE (chf)
294 DEALLOCATE (uv)
295 CALL timestop(handle)
296 END SUBROUTINE cp_decpl_ddapc_forces
297
298! **************************************************************************************************
299!> \brief Evaluation of the pulay forces due to the fitted charge density
300!> \param qs_env ...
301!> \par History
302!> 08.2005 created [tlaino]
303!> \author Teodoro Laino
304! **************************************************************************************************
305 SUBROUTINE reset_ch_pulay(qs_env)
306 TYPE(qs_environment_type), POINTER :: qs_env
307
308 CHARACTER(len=*), PARAMETER :: routinen = 'reset_ch_pulay'
309
310 INTEGER :: handle, ind
311 TYPE(qs_force_type), DIMENSION(:), POINTER :: force
312
313 CALL timeset(routinen, handle)
314 CALL get_qs_env(qs_env=qs_env, &
315 force=force)
316 DO ind = 1, SIZE(force)
317 force(ind)%ch_pulay = 0.0_dp
318 END DO
319 CALL timestop(handle)
320 END SUBROUTINE reset_ch_pulay
321
322! **************************************************************************************************
323!> \brief computes energy and derivatives given a set of charges
324!> \param ddapc_restraint_control ...
325!> \param n_gauss ...
326!> \param uv derivate of energy wrt the corresponding charge entry
327!> \param charges current value of the charges (one number for each gaussian used)
328!>
329!> \param energy_res energy due to the restraint
330!> \par History
331!> 02.2006 [Joost VandeVondele]
332!> modified [Teo]
333!> \note
334!> should be easy to adapt for other specialized cases
335! **************************************************************************************************
336 SUBROUTINE evaluate_restraint_functional(ddapc_restraint_control, n_gauss, uv, &
337 charges, energy_res)
338 TYPE(ddapc_restraint_type), INTENT(INOUT) :: ddapc_restraint_control
339 INTEGER, INTENT(in) :: n_gauss
340 REAL(kind=dp), DIMENSION(:) :: uv
341 REAL(kind=dp), DIMENSION(:), POINTER :: charges
342 REAL(kind=dp), INTENT(INOUT) :: energy_res
343
344 INTEGER :: i, ind
345 REAL(kind=dp) :: de, order_p
346
347! order parameter (i.e. the sum of the charges of the selected atoms)
348
349 order_p = 0.0_dp
350 DO i = 1, ddapc_restraint_control%natoms
351 ind = (ddapc_restraint_control%atoms(i) - 1)*n_gauss
352 order_p = order_p + ddapc_restraint_control%coeff(i)*sum(charges(ind + 1:ind + n_gauss))
353 END DO
354 ddapc_restraint_control%ddapc_order_p = order_p
355
356 SELECT CASE (ddapc_restraint_control%functional_form)
357 CASE (do_ddapc_restraint)
358 ! the restraint energy
359 energy_res = ddapc_restraint_control%strength*(order_p - ddapc_restraint_control%target)**2.0_dp
360
361 ! derivative of the energy
362 de = 2.0_dp*ddapc_restraint_control%strength*(order_p - ddapc_restraint_control%target)
363 DO i = 1, ddapc_restraint_control%natoms
364 ind = (ddapc_restraint_control%atoms(i) - 1)*n_gauss
365 uv(ind + 1:ind + n_gauss) = de*ddapc_restraint_control%coeff(i)
366 END DO
368 energy_res = ddapc_restraint_control%strength*(order_p - ddapc_restraint_control%target)
369
370 ! derivative of the energy
371 DO i = 1, ddapc_restraint_control%natoms
372 ind = (ddapc_restraint_control%atoms(i) - 1)*n_gauss
373 uv(ind + 1:ind + n_gauss) = ddapc_restraint_control%strength*ddapc_restraint_control%coeff(i)
374 END DO
375
376 CASE DEFAULT
377 cpabort("")
378 END SELECT
379
380 END SUBROUTINE evaluate_restraint_functional
381
382! **************************************************************************************************
383!> \brief computes derivatives for DDAPC restraint
384!> \param qs_env ...
385!> \param ddapc_restraint_control ...
386!> \param dq ...
387!> \param charges ...
388!> \param n_gauss ...
389!> \param particle_set ...
390!> \par History
391!> 02.2006 [Joost VandeVondele]
392!> modified [Teo]
393!> \note
394!> should be easy to adapt for other specialized cases
395! **************************************************************************************************
396 SUBROUTINE restraint_functional_force(qs_env, ddapc_restraint_control, dq, charges, &
397 n_gauss, particle_set)
398
399 TYPE(qs_environment_type), POINTER :: qs_env
400 TYPE(ddapc_restraint_type), INTENT(INOUT) :: ddapc_restraint_control
401 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: dq
402 REAL(kind=dp), DIMENSION(:), POINTER :: charges
403 INTEGER, INTENT(in) :: n_gauss
404 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
405
406 CHARACTER(len=*), PARAMETER :: routinen = 'restraint_functional_force'
407
408 INTEGER :: handle, i, iatom, ikind, j, k, natom
409 INTEGER, ALLOCATABLE, DIMENSION(:) :: atom_of_kind, kind_of
410 REAL(kind=dp) :: dum
411 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: uv
412 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: chf
413 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
414 TYPE(mp_para_env_type), POINTER :: para_env
415 TYPE(qs_force_type), DIMENSION(:), POINTER :: force
416
417 NULLIFY (para_env)
418 CALL timeset(routinen, handle)
419 natom = SIZE(particle_set)
420 CALL get_qs_env(qs_env=qs_env, &
421 atomic_kind_set=atomic_kind_set, &
422 para_env=para_env, &
423 force=force)
424 ALLOCATE (chf(3, natom))
425 CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, &
426 atom_of_kind=atom_of_kind, &
427 kind_of=kind_of)
428
429 ALLOCATE (uv(SIZE(dq, 1)))
430 uv = 0.0_dp
431 CALL evaluate_restraint_functional(ddapc_restraint_control, n_gauss, uv, &
432 charges, dum)
433 DO k = 1, natom
434 DO j = 1, 3
435 chf(j, k) = dot_product(uv, dq(:, k, j))
436 END DO
437 END DO
438 !NB now that get_ddapc returns dq that's spread over nodes, must reduce chf here
439 CALL para_env%sum(chf)
440 DO iatom = 1, natom
441 ikind = kind_of(iatom)
442 i = atom_of_kind(iatom)
443 force(ikind)%ch_pulay(1:3, i) = force(ikind)%ch_pulay(1:3, i) + chf(1:3, iatom)
444 END DO
445 DEALLOCATE (chf)
446 DEALLOCATE (uv)
447 CALL timestop(handle)
448
449 END SUBROUTINE restraint_functional_force
450
451! **************************************************************************************************
452!> \brief Evaluates the electrostatic potential due to a simple solvation model
453!> Spherical cavity in a dieletric medium
454!> \param qs_env ...
455!> \param solvation_section ...
456!> \param particle_set ...
457!> \param radii ...
458!> \param dq ...
459!> \param charges ...
460!> \par History
461!> 08.2006 created [tlaino]
462!> \author Teodoro Laino
463! **************************************************************************************************
464 SUBROUTINE solvation_ddapc_force(qs_env, solvation_section, particle_set, &
465 radii, dq, charges)
466 TYPE(qs_environment_type), POINTER :: qs_env
467 TYPE(section_vals_type), POINTER :: solvation_section
468 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
469 REAL(kind=dp), DIMENSION(:), POINTER :: radii
470 REAL(kind=dp), DIMENSION(:, :, :), OPTIONAL, &
471 POINTER :: dq
472 REAL(kind=dp), DIMENSION(:), OPTIONAL, POINTER :: charges
473
474 INTEGER :: i, ip1, ip2, iparticle1, iparticle2, l, &
475 lmax, n_rep1, n_rep2, weight
476 INTEGER, DIMENSION(:), POINTER :: list
477 LOGICAL :: fixed_center
478 REAL(kind=dp) :: center(3), dcos1(3), dcos2(3), dpos1(3), dpos2(3), eps_in, eps_out, &
479 factor1(3), factor2(3), lr, mass, mycos, pos1, pos1i, pos2, pos2i, ptcos, q1t, q2t, &
480 r1(3), r1s, r2(3), r2s, rs, rvec(3)
481 REAL(kind=dp), DIMENSION(:), POINTER :: pos, r0
482 REAL(kind=dp), DIMENSION(:, :), POINTER :: d_el, locp, m
483
484 fixed_center = .false.
485 NULLIFY (d_el, m)
486 eps_in = 1.0_dp
487 CALL section_vals_val_get(solvation_section, "EPS_OUT", r_val=eps_out)
488 CALL section_vals_val_get(solvation_section, "LMAX", i_val=lmax)
489 CALL section_vals_val_get(solvation_section, "SPHERE%RADIUS", r_val=rs)
490 CALL section_vals_val_get(solvation_section, "SPHERE%CENTER%XYZ", n_rep_val=n_rep1)
491 IF (n_rep1 /= 0) THEN
492 CALL section_vals_val_get(solvation_section, "SPHERE%CENTER%XYZ", r_vals=r0)
493 center = r0
494 ELSE
495 CALL section_vals_val_get(solvation_section, "SPHERE%CENTER%ATOM_LIST", &
496 n_rep_val=n_rep2)
497 IF (n_rep2 /= 0) THEN
498 CALL section_vals_val_get(solvation_section, "SPHERE%CENTER%ATOM_LIST", i_vals=list)
499 CALL section_vals_val_get(solvation_section, "SPHERE%CENTER%WEIGHT_TYPE", i_val=weight)
500 ALLOCATE (r0(SIZE(list)))
501 SELECT CASE (weight)
502 CASE (weight_type_unit)
503 r0 = 0.0_dp
504 DO i = 1, SIZE(list)
505 r0 = r0 + particle_set(list(i))%r
506 END DO
507 r0 = r0/real(SIZE(list), kind=dp)
508 CASE (weight_type_mass)
509 r0 = 0.0_dp
510 mass = 0.0_dp
511 DO i = 1, SIZE(list)
512 r0 = r0 + particle_set(list(i))%r*particle_set(list(i))%atomic_kind%mass
513 mass = mass + particle_set(list(i))%atomic_kind%mass
514 END DO
515 r0 = r0/mass
516 END SELECT
517 center = r0
518 DEALLOCATE (r0)
519 END IF
520 END IF
521 cpassert(n_rep1 /= 0 .OR. n_rep2 /= 0)
522 ! Potential calculation
523 ALLOCATE (locp(0:lmax, SIZE(particle_set)))
524 ALLOCATE (pos(SIZE(particle_set)))
525 ALLOCATE (d_el(3, SIZE(particle_set)))
526 d_el = 0.0_dp
527 ! Determining the single atomic contribution to the dielectric dipole
528 DO i = 1, SIZE(particle_set)
529 rvec = particle_set(i)%r - center
530 r2s = dot_product(rvec, rvec)
531 r1s = sqrt(r2s)
532 locp(:, i) = 0.0_dp
533 IF (r1s /= 0.0_dp) THEN
534 DO l = 0, lmax
535 locp(l, i) = (r1s**l*real(l + 1, kind=dp)*(eps_in - eps_out))/ &
536 (rs**(2*l + 1)*eps_in*(real(l, kind=dp)*eps_in + real(l + 1, kind=dp)*eps_out))
537 END DO
538 END IF
539 pos(i) = r1s
540 END DO
541 ! Computes the full derivatives of the interaction energy
542 DO iparticle1 = 1, SIZE(particle_set)
543 ip1 = (iparticle1 - 1)*SIZE(radii)
544 q1t = sum(charges(ip1 + 1:ip1 + SIZE(radii)))
545 DO iparticle2 = 1, iparticle1
546 ip2 = (iparticle2 - 1)*SIZE(radii)
547 q2t = sum(charges(ip2 + 1:ip2 + SIZE(radii)))
548 !
549 r1 = particle_set(iparticle1)%r - center
550 r2 = particle_set(iparticle2)%r - center
551 pos1 = pos(iparticle1)
552 pos2 = pos(iparticle2)
553 factor1 = 0.0_dp
554 factor2 = 0.0_dp
555 IF (pos1*pos2 /= 0.0_dp) THEN
556 pos1i = 1.0_dp/pos1
557 pos2i = 1.0_dp/pos2
558 dpos1 = pos1i*r1
559 dpos2 = pos2i*r2
560 ptcos = dot_product(r1, r2)
561 mycos = ptcos/(pos1*pos2)
562 IF (abs(mycos) > 1.0_dp) mycos = sign(1.0_dp, mycos)
563 dcos1 = (r2*(pos1*pos2) - pos2*dpos1*ptcos)/(pos1*pos2)**2
564 dcos2 = (r1*(pos1*pos2) - pos1*dpos2*ptcos)/(pos1*pos2)**2
565
566 DO l = 1, lmax
567 lr = real(l, kind=dp)
568 factor1 = factor1 + lr*locp(l, iparticle2)*pos1**(l - 1)*legendre(mycos, l, 0)*dpos1 &
569 + locp(l, iparticle2)*pos1**l*dlegendre(mycos, l, 0)*dcos1
570 factor2 = factor2 + lr*locp(l, iparticle1)*pos2**(l - 1)*legendre(mycos, l, 0)*dpos2 &
571 + locp(l, iparticle1)*pos2**l*dlegendre(mycos, l, 0)*dcos2
572 END DO
573 END IF
574 factor1 = factor1*q1t*q2t
575 factor2 = factor2*q1t*q2t
576 d_el(1:3, iparticle1) = d_el(1:3, iparticle1) + 0.5_dp*factor1
577 d_el(1:3, iparticle2) = d_el(1:3, iparticle2) + 0.5_dp*factor2
578 END DO
579 END DO
580 DEALLOCATE (pos)
581 DEALLOCATE (locp)
582 m => qs_env%cp_ddapc_env%Ms
583 CALL cp_decpl_ddapc_forces(qs_env, m, charges, dq, d_el, particle_set)
584 DEALLOCATE (d_el)
585 END SUBROUTINE solvation_ddapc_force
586
587END MODULE cp_ddapc_forces
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.
Handles all functions related to the CELL.
Definition cell_types.F:15
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
Density Derived atomic point charges from a QM calculation (see J. Chem. Phys. Vol....
subroutine, public solvation_ddapc_force(qs_env, solvation_section, particle_set, radii, dq, charges)
Evaluates the electrostatic potential due to a simple solvation model Spherical cavity in a dieletric...
recursive subroutine, public ewald_ddapc_force(qs_env, coeff, apply_qmmm_periodic, factor, multipole_section, cell, particle_set, radii, dq, charges)
Evaluates the Ewald term E2 and E3 energy term for the decoupling/coupling of periodic images.
subroutine, public restraint_functional_force(qs_env, ddapc_restraint_control, dq, charges, n_gauss, particle_set)
computes derivatives for DDAPC restraint
subroutine, public evaluate_restraint_functional(ddapc_restraint_control, n_gauss, uv, charges, energy_res)
computes energy and derivatives given a set of charges
subroutine, public reset_ch_pulay(qs_env)
Evaluation of the pulay forces due to the fitted charge density.
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public do_ddapc_constraint
integer, parameter, public weight_type_unit
integer, parameter, public weight_type_mass
integer, parameter, public do_ddapc_restraint
objects that represent the structure of input sections and the data contained in an input section
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
An array-based list which grows on demand. When the internal array is full, a new array of twice the ...
Definition list.F:24
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi
real(kind=dp), parameter, public rootpi
real(kind=dp), parameter, public fourpi
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 particle information.
different utils that are useful to manipulate splines on the regular grid of a pw
real(kind=dp) function, dimension(3), public eval_d_interp_spl3_pbc(vec, pw)
Evaluates the derivatives of the PBC interpolated Spline (pw) function on the generic input vector (v...
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.
Calculate spherical harmonics.
real(kind=dp) function, public legendre(x, l, m)
...
real(kind=dp) function, public dlegendre(x, l, m)
...
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
Definition cell_types.F:60
stores all the informations relevant to an mpi environment