Line data Source code
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 charge equilibration in xTB
10 : !> \author JGH
11 : ! **************************************************************************************************
12 : MODULE xtb_eeq
13 : USE atomic_kind_types, ONLY: atomic_kind_type,&
14 : get_atomic_kind_set
15 : USE atprop_types, ONLY: atprop_array_init,&
16 : atprop_type
17 : USE cell_types, ONLY: cell_type,&
18 : pbc
19 : USE cp_blacs_env, ONLY: cp_blacs_env_type
20 : USE cp_control_types, ONLY: dft_control_type,&
21 : xtb_control_type
22 : USE cp_log_handling, ONLY: cp_logger_get_default_unit_nr
23 : USE distribution_1d_types, ONLY: distribution_1d_type
24 : USE eeq_input, ONLY: eeq_solver_type
25 : USE eeq_method, ONLY: eeq_efield_energy,&
26 : eeq_efield_force_loc,&
27 : eeq_efield_force_periodic,&
28 : eeq_efield_pot,&
29 : eeq_solver
30 : USE ewald_environment_types, ONLY: ewald_env_get,&
31 : ewald_environment_type
32 : USE ewald_pw_types, ONLY: ewald_pw_type
33 : USE kinds, ONLY: dp
34 : USE mathconstants, ONLY: oorootpi
35 : USE message_passing, ONLY: mp_para_env_type
36 : USE particle_types, ONLY: particle_type
37 : USE qs_dispersion_cnum, ONLY: dcnum_type
38 : USE qs_environment_types, ONLY: get_qs_env,&
39 : qs_environment_type
40 : USE qs_force_types, ONLY: qs_force_type
41 : USE qs_kind_types, ONLY: get_qs_kind,&
42 : qs_kind_type
43 : USE qs_neighbor_list_types, ONLY: get_iterator_info,&
44 : neighbor_list_iterate,&
45 : neighbor_list_iterator_create,&
46 : neighbor_list_iterator_p_type,&
47 : neighbor_list_iterator_release,&
48 : neighbor_list_set_p_type
49 : USE spme, ONLY: spme_forces,&
50 : spme_virial
51 : USE virial_methods, ONLY: virial_pair_force
52 : USE virial_types, ONLY: virial_type
53 : USE xtb_types, ONLY: get_xtb_atom_param,&
54 : xtb_atom_type
55 : #include "./base/base_uses.f90"
56 :
57 : IMPLICIT NONE
58 :
59 : PRIVATE
60 :
61 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'xtb_eeq'
62 :
63 : PUBLIC :: xtb_eeq_calculation, xtb_eeq_forces, xtb_eeq_lagrange
64 :
65 : CONTAINS
66 :
67 : ! **************************************************************************************************
68 : !> \brief ...
69 : !> \param qs_env ...
70 : !> \param charges ...
71 : !> \param cnumbers ...
72 : !> \param eeq_sparam ...
73 : !> \param eeq_energy ...
74 : !> \param ef_energy ...
75 : !> \param lambda ...
76 : ! **************************************************************************************************
77 2104 : SUBROUTINE xtb_eeq_calculation(qs_env, charges, cnumbers, &
78 : eeq_sparam, eeq_energy, ef_energy, lambda)
79 :
80 : TYPE(qs_environment_type), POINTER :: qs_env
81 : REAL(KIND=dp), DIMENSION(:), INTENT(INOUT) :: charges
82 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: cnumbers
83 : TYPE(eeq_solver_type), INTENT(IN) :: eeq_sparam
84 : REAL(KIND=dp), INTENT(INOUT) :: eeq_energy, ef_energy, lambda
85 :
86 : CHARACTER(len=*), PARAMETER :: routineN = 'xtb_eeq_calculation'
87 :
88 : INTEGER :: enshift_type, handle, iatom, ikind, &
89 : iunit, jkind, natom, nkind
90 2104 : INTEGER, ALLOCATABLE, DIMENSION(:) :: kind_of
91 : LOGICAL :: defined, do_ewald
92 : REAL(KIND=dp) :: ala, alb, cn, esg, gama, kappa, scn, &
93 : sgamma, totalcharge, xi
94 2104 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: chia, efr, gam
95 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: gab
96 2104 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
97 : TYPE(atprop_type), POINTER :: atprop
98 : TYPE(cell_type), POINTER :: cell
99 : TYPE(cp_blacs_env_type), POINTER :: blacs_env
100 : TYPE(dft_control_type), POINTER :: dft_control
101 : TYPE(ewald_environment_type), POINTER :: ewald_env
102 : TYPE(ewald_pw_type), POINTER :: ewald_pw
103 : TYPE(mp_para_env_type), POINTER :: para_env
104 2104 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
105 2104 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
106 : TYPE(xtb_atom_type), POINTER :: xtb_atom_a, xtb_atom_b
107 : TYPE(xtb_control_type), POINTER :: xtb_control
108 :
109 2104 : CALL timeset(routineN, handle)
110 :
111 2104 : iunit = cp_logger_get_default_unit_nr()
112 :
113 : CALL get_qs_env(qs_env, &
114 : qs_kind_set=qs_kind_set, &
115 : atomic_kind_set=atomic_kind_set, &
116 : particle_set=particle_set, &
117 : cell=cell, &
118 : atprop=atprop, &
119 2104 : dft_control=dft_control)
120 2104 : CALL get_qs_env(qs_env, nkind=nkind, natom=natom)
121 :
122 2104 : xtb_control => dft_control%qs_control%xtb_control
123 :
124 2104 : totalcharge = dft_control%charge
125 :
126 2104 : IF (atprop%energy) THEN
127 0 : CALL atprop_array_init(atprop%atecoul, natom)
128 : END IF
129 :
130 : ! gamma[a,b]
131 12624 : ALLOCATE (gab(nkind, nkind), gam(nkind))
132 2104 : gab = 0.0_dp
133 2104 : gam = 0.0_dp
134 7012 : DO ikind = 1, nkind
135 4908 : CALL get_qs_kind(qs_kind_set(ikind), xtb_parameter=xtb_atom_a)
136 4908 : CALL get_xtb_atom_param(xtb_atom_a, defined=defined)
137 4908 : IF (.NOT. defined) CYCLE
138 4908 : CALL get_xtb_atom_param(xtb_atom_a, alpg=ala, eta=gama)
139 4908 : gam(ikind) = gama
140 24228 : DO jkind = 1, nkind
141 12308 : CALL get_qs_kind(qs_kind_set(jkind), xtb_parameter=xtb_atom_b)
142 12308 : CALL get_xtb_atom_param(xtb_atom_b, defined=defined)
143 12308 : IF (.NOT. defined) CYCLE
144 12308 : CALL get_xtb_atom_param(xtb_atom_b, alpg=alb)
145 : !
146 29524 : gab(ikind, jkind) = SQRT(1._dp/(ala*ala + alb*alb))
147 : !
148 : END DO
149 : END DO
150 :
151 : ! Chi[a,a]
152 2104 : enshift_type = xtb_control%enshift_type
153 2104 : IF (enshift_type == 0) THEN
154 0 : enshift_type = 2
155 0 : IF (ALL(cell%perd == 0)) enshift_type = 1
156 : END IF
157 2104 : sgamma = 8.0_dp ! see D4 for periodic systems paper
158 2104 : esg = 1.0_dp + EXP(sgamma)
159 6312 : ALLOCATE (chia(natom))
160 2104 : CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, kind_of=kind_of)
161 12048 : DO iatom = 1, natom
162 9944 : ikind = kind_of(iatom)
163 9944 : CALL get_qs_kind(qs_kind_set(ikind), xtb_parameter=xtb_atom_a)
164 9944 : CALL get_xtb_atom_param(xtb_atom_a, xi=xi, kappa0=kappa)
165 : !
166 9944 : IF (enshift_type == 1) THEN
167 9944 : scn = SQRT(cnumbers(iatom)) + 1.0e-14_dp
168 0 : ELSE IF (enshift_type == 2) THEN
169 0 : cn = cnumbers(iatom)/esg
170 0 : scn = LOG(esg/(esg - cnumbers(iatom)))
171 : ELSE
172 0 : CPABORT("Unknown enshift_type")
173 : END IF
174 21992 : chia(iatom) = xi - kappa*scn
175 : !
176 : END DO
177 :
178 2104 : ef_energy = 0.0_dp
179 2104 : IF (dft_control%apply_period_efield .OR. dft_control%apply_efield .OR. &
180 : dft_control%apply_efield_field) THEN
181 996 : ALLOCATE (efr(natom))
182 1660 : efr(1:natom) = 0.0_dp
183 332 : CALL eeq_efield_pot(qs_env, efr)
184 3432 : chia(1:natom) = chia(1:natom) + efr(1:natom)
185 : END IF
186 :
187 2104 : do_ewald = xtb_control%do_ewald
188 :
189 2104 : CALL get_qs_env(qs_env, para_env=para_env, blacs_env=blacs_env)
190 2104 : IF (do_ewald) THEN
191 : CALL get_qs_env(qs_env=qs_env, &
192 990 : ewald_env=ewald_env, ewald_pw=ewald_pw)
193 : CALL eeq_solver(charges, lambda, eeq_energy, &
194 : particle_set, kind_of, cell, chia, gam, gab, &
195 : para_env, blacs_env, dft_control, eeq_sparam, &
196 : totalcharge=totalcharge, ewald=do_ewald, &
197 990 : ewald_env=ewald_env, ewald_pw=ewald_pw, iounit=iunit)
198 : ELSE
199 : CALL eeq_solver(charges, lambda, eeq_energy, &
200 : particle_set, kind_of, cell, chia, gam, gab, &
201 : para_env, blacs_env, dft_control, eeq_sparam, &
202 1114 : totalcharge=totalcharge, iounit=iunit)
203 : END IF
204 :
205 2104 : IF (dft_control%apply_period_efield .OR. dft_control%apply_efield .OR. &
206 : dft_control%apply_efield_field) THEN
207 332 : CALL eeq_efield_energy(qs_env, charges, ef_energy)
208 1660 : eeq_energy = eeq_energy - SUM(charges*efr)
209 332 : DEALLOCATE (efr)
210 : END IF
211 :
212 2104 : DEALLOCATE (gab, gam, chia)
213 :
214 2104 : CALL timestop(handle)
215 :
216 4208 : END SUBROUTINE xtb_eeq_calculation
217 :
218 : ! **************************************************************************************************
219 : !> \brief ...
220 : !> \param qs_env ...
221 : !> \param charges ...
222 : !> \param dcharges ...
223 : !> \param qlagrange ...
224 : !> \param cnumbers ...
225 : !> \param dcnum ...
226 : !> \param eeq_sparam ...
227 : ! **************************************************************************************************
228 68 : SUBROUTINE xtb_eeq_forces(qs_env, charges, dcharges, qlagrange, cnumbers, dcnum, eeq_sparam)
229 :
230 : TYPE(qs_environment_type), POINTER :: qs_env
231 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: charges, dcharges
232 : REAL(KIND=dp), DIMENSION(:), INTENT(OUT) :: qlagrange
233 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: cnumbers
234 : TYPE(dcnum_type), DIMENSION(:), INTENT(IN) :: dcnum
235 : TYPE(eeq_solver_type), INTENT(IN) :: eeq_sparam
236 :
237 : CHARACTER(len=*), PARAMETER :: routineN = 'xtb_eeq_forces'
238 :
239 : INTEGER :: atom_a, atom_b, atom_c, enshift_type, &
240 : handle, i, ia, iatom, ikind, iunit, &
241 : jatom, jkind, katom, kkind, natom, &
242 : nkind
243 68 : INTEGER, ALLOCATABLE, DIMENSION(:) :: atom_of_kind, kind_of
244 : LOGICAL :: defined, do_ewald, use_virial
245 : REAL(KIND=dp) :: ala, alb, alpha, cn, ctot, dr, dr2, drk, &
246 : elag, esg, fe, gam2, gama, grc, kappa, &
247 : qlam, qq, qq1, qq2, rcut, scn, sgamma, &
248 : totalcharge, xi
249 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: gam
250 68 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: epforce, gab
251 : REAL(KIND=dp), DIMENSION(3) :: fdik, ri, rij, rik, rj
252 : REAL(KIND=dp), DIMENSION(3, 3) :: pvir
253 68 : REAL(KIND=dp), DIMENSION(:), POINTER :: chrgx, dchia, qlag
254 68 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
255 : TYPE(atprop_type), POINTER :: atprop
256 : TYPE(cell_type), POINTER :: cell
257 : TYPE(cp_blacs_env_type), POINTER :: blacs_env
258 : TYPE(dft_control_type), POINTER :: dft_control
259 : TYPE(distribution_1d_type), POINTER :: local_particles
260 : TYPE(ewald_environment_type), POINTER :: ewald_env
261 : TYPE(ewald_pw_type), POINTER :: ewald_pw
262 : TYPE(mp_para_env_type), POINTER :: para_env
263 : TYPE(neighbor_list_iterator_p_type), &
264 68 : DIMENSION(:), POINTER :: nl_iterator
265 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
266 68 : POINTER :: sab_tbe
267 68 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
268 68 : TYPE(qs_force_type), DIMENSION(:), POINTER :: force
269 68 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
270 : TYPE(virial_type), POINTER :: virial
271 : TYPE(xtb_atom_type), POINTER :: xtb_atom_a, xtb_atom_b
272 : TYPE(xtb_control_type), POINTER :: xtb_control
273 :
274 68 : CALL timeset(routineN, handle)
275 :
276 68 : iunit = cp_logger_get_default_unit_nr()
277 :
278 : CALL get_qs_env(qs_env, &
279 : qs_kind_set=qs_kind_set, &
280 : atomic_kind_set=atomic_kind_set, &
281 : particle_set=particle_set, &
282 : atprop=atprop, &
283 : force=force, &
284 : virial=virial, &
285 : cell=cell, &
286 68 : dft_control=dft_control)
287 68 : CALL get_qs_env(qs_env, nkind=nkind, natom=natom)
288 68 : use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
289 :
290 68 : xtb_control => dft_control%qs_control%xtb_control
291 :
292 68 : totalcharge = dft_control%charge
293 :
294 : CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, &
295 68 : atom_of_kind=atom_of_kind, kind_of=kind_of)
296 :
297 : ! gamma[a,b]
298 408 : ALLOCATE (gab(nkind, nkind), gam(nkind))
299 68 : gab = 0.0_dp
300 224 : DO ikind = 1, nkind
301 156 : CALL get_qs_kind(qs_kind_set(ikind), xtb_parameter=xtb_atom_a)
302 156 : CALL get_xtb_atom_param(xtb_atom_a, defined=defined)
303 156 : IF (.NOT. defined) CYCLE
304 156 : CALL get_xtb_atom_param(xtb_atom_a, alpg=ala, eta=gama)
305 156 : gam(ikind) = gama
306 780 : DO jkind = 1, nkind
307 400 : CALL get_qs_kind(qs_kind_set(jkind), xtb_parameter=xtb_atom_b)
308 400 : CALL get_xtb_atom_param(xtb_atom_b, defined=defined)
309 400 : IF (.NOT. defined) CYCLE
310 400 : CALL get_xtb_atom_param(xtb_atom_b, alpg=alb)
311 : !
312 956 : gab(ikind, jkind) = SQRT(1._dp/(ala*ala + alb*alb))
313 : !
314 : END DO
315 : END DO
316 :
317 204 : ALLOCATE (qlag(natom))
318 :
319 68 : do_ewald = xtb_control%do_ewald
320 :
321 68 : CALL get_qs_env(qs_env, para_env=para_env, blacs_env=blacs_env)
322 68 : IF (do_ewald) THEN
323 : CALL get_qs_env(qs_env=qs_env, &
324 46 : ewald_env=ewald_env, ewald_pw=ewald_pw)
325 : CALL eeq_solver(qlag, qlam, elag, &
326 : particle_set, kind_of, cell, -dcharges, gam, gab, &
327 : para_env, blacs_env, dft_control, eeq_sparam, &
328 314 : ewald=do_ewald, ewald_env=ewald_env, ewald_pw=ewald_pw, iounit=iunit)
329 : ELSE
330 : CALL eeq_solver(qlag, qlam, elag, &
331 : particle_set, kind_of, cell, -dcharges, gam, gab, &
332 102 : para_env, blacs_env, dft_control, eeq_sparam, iounit=iunit)
333 : END IF
334 :
335 68 : enshift_type = xtb_control%enshift_type
336 68 : IF (enshift_type == 0) THEN
337 0 : enshift_type = 2
338 0 : IF (ALL(cell%perd == 0)) enshift_type = 1
339 : END IF
340 68 : sgamma = 8.0_dp ! see D4 for periodic systems paper
341 68 : esg = 1.0_dp + EXP(sgamma)
342 272 : ALLOCATE (chrgx(natom), dchia(natom))
343 416 : DO iatom = 1, natom
344 348 : ikind = kind_of(iatom)
345 348 : CALL get_qs_kind(qs_kind_set(ikind), xtb_parameter=xtb_atom_a)
346 348 : CALL get_xtb_atom_param(xtb_atom_a, xi=xi, kappa0=kappa)
347 : !
348 348 : ctot = 0.5_dp*(charges(iatom) - qlag(iatom))
349 416 : IF (enshift_type == 1) THEN
350 348 : scn = SQRT(cnumbers(iatom)) + 1.0e-14_dp
351 348 : dchia(iatom) = -ctot*kappa/scn
352 0 : ELSE IF (enshift_type == 2) THEN
353 0 : cn = cnumbers(iatom)
354 0 : scn = 1.0_dp/(esg - cn)
355 0 : dchia(iatom) = -ctot*kappa*scn
356 : ELSE
357 0 : CPABORT("Unknown enshift_type")
358 : END IF
359 : END DO
360 :
361 : ! Efield
362 68 : IF (dft_control%apply_period_efield) THEN
363 8 : CALL eeq_efield_force_periodic(qs_env, charges, qlag)
364 60 : ELSE IF (dft_control%apply_efield) THEN
365 8 : CALL eeq_efield_force_loc(qs_env, charges, qlag)
366 52 : ELSE IF (dft_control%apply_efield_field) THEN
367 0 : CPABORT("apply field")
368 : END IF
369 :
370 : ! Forces from q*X
371 : CALL get_qs_env(qs_env=qs_env, &
372 68 : local_particles=local_particles)
373 224 : DO ikind = 1, nkind
374 398 : DO ia = 1, local_particles%n_el(ikind)
375 174 : iatom = local_particles%list(ikind)%array(ia)
376 174 : atom_a = atom_of_kind(iatom)
377 1580 : DO i = 1, dcnum(iatom)%neighbors
378 1250 : katom = dcnum(iatom)%nlist(i)
379 1250 : kkind = kind_of(katom)
380 1250 : atom_c = atom_of_kind(katom)
381 5000 : rik = dcnum(iatom)%rik(:, i)
382 5000 : drk = SQRT(SUM(rik(:)**2))
383 1424 : IF (drk > 1.e-3_dp) THEN
384 5000 : fdik(:) = dchia(iatom)*dcnum(iatom)%dvals(i)*rik(:)/drk
385 5000 : force(ikind)%rho_elec(:, atom_a) = force(ikind)%rho_elec(:, atom_a) - fdik(:)
386 5000 : force(kkind)%rho_elec(:, atom_c) = force(kkind)%rho_elec(:, atom_c) + fdik(:)
387 1250 : IF (use_virial) THEN
388 1084 : CALL virial_pair_force(virial%pv_virial, -1._dp, fdik, rik)
389 : END IF
390 : END IF
391 : END DO
392 : END DO
393 : END DO
394 :
395 : ! Forces from (0.5*q+l)*dA/dR*q
396 68 : IF (do_ewald) THEN
397 46 : CALL get_qs_env(qs_env, sab_tbe=sab_tbe)
398 46 : CALL ewald_env_get(ewald_env, alpha=alpha, rcut=rcut)
399 46 : rcut = 1.0_dp*rcut
400 46 : CALL neighbor_list_iterator_create(nl_iterator, sab_tbe)
401 54750 : DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
402 : CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, &
403 54704 : iatom=iatom, jatom=jatom, r=rij)
404 54704 : atom_a = atom_of_kind(iatom)
405 54704 : atom_b = atom_of_kind(jatom)
406 : !
407 218816 : dr2 = SUM(rij**2)
408 54704 : dr = SQRT(dr2)
409 54704 : IF (dr > rcut .OR. dr < 1.E-6_dp) CYCLE
410 6533 : fe = 1.0_dp
411 6533 : IF (iatom == jatom) fe = 0.5_dp
412 6533 : qq = (0.5_dp*charges(iatom) - qlag(iatom))*charges(jatom)
413 6533 : gama = gab(ikind, jkind)
414 6533 : gam2 = gama*gama
415 : grc = 2._dp*gama*EXP(-gam2*dr2)*oorootpi/dr - erf(gama*dr)/dr2 &
416 6533 : - 2._dp*alpha*EXP(-alpha**2*dr2)*oorootpi/dr + erf(alpha*dr)/dr2
417 6533 : qq1 = (0.5_dp*charges(iatom) - qlag(iatom))*charges(jatom)
418 6533 : qq2 = (0.5_dp*charges(jatom) - qlag(jatom))*charges(iatom)
419 26132 : fdik(:) = -qq1*grc*rij(:)/dr
420 26132 : force(ikind)%rho_elec(:, atom_a) = force(ikind)%rho_elec(:, atom_a) + fdik(:)
421 26132 : force(jkind)%rho_elec(:, atom_b) = force(jkind)%rho_elec(:, atom_b) - fdik(:)
422 6533 : IF (use_virial) THEN
423 5586 : CALL virial_pair_force(virial%pv_virial, fe, fdik, rij)
424 : END IF
425 26132 : fdik(:) = qq2*grc*rij(:)/dr
426 26132 : force(ikind)%rho_elec(:, atom_a) = force(ikind)%rho_elec(:, atom_a) - fdik(:)
427 26132 : force(jkind)%rho_elec(:, atom_b) = force(jkind)%rho_elec(:, atom_b) + fdik(:)
428 6579 : IF (use_virial) THEN
429 5586 : CALL virial_pair_force(virial%pv_virial, -fe, fdik, rij)
430 : END IF
431 : END DO
432 46 : CALL neighbor_list_iterator_release(nl_iterator)
433 : ELSE
434 80 : DO ikind = 1, nkind
435 120 : DO ia = 1, local_particles%n_el(ikind)
436 40 : iatom = local_particles%list(ikind)%array(ia)
437 40 : atom_a = atom_of_kind(iatom)
438 160 : ri(1:3) = particle_set(iatom)%r(1:3)
439 246 : DO jatom = 1, natom
440 148 : IF (iatom == jatom) CYCLE
441 108 : jkind = kind_of(jatom)
442 108 : atom_b = atom_of_kind(jatom)
443 108 : qq = (0.5_dp*charges(iatom) - qlag(iatom))*charges(jatom)
444 432 : rj(1:3) = particle_set(jatom)%r(1:3)
445 432 : rij(1:3) = ri(1:3) - rj(1:3)
446 432 : rij = pbc(rij, cell)
447 432 : dr2 = SUM(rij**2)
448 108 : dr = SQRT(dr2)
449 108 : gama = gab(ikind, jkind)
450 108 : gam2 = gama*gama
451 108 : grc = 2._dp*gama*EXP(-gam2*dr2)*oorootpi/dr - erf(gama*dr)/dr2
452 432 : fdik(:) = qq*grc*rij(:)/dr
453 432 : force(ikind)%rho_elec(:, atom_a) = force(ikind)%rho_elec(:, atom_a) + fdik(:)
454 432 : force(jkind)%rho_elec(:, atom_b) = force(jkind)%rho_elec(:, atom_b) - fdik(:)
455 148 : IF (use_virial) THEN
456 12 : CALL virial_pair_force(virial%pv_virial, -1._dp, fdik, rij)
457 : END IF
458 : END DO
459 : END DO
460 : END DO
461 : END IF
462 :
463 : ! Forces from Ewald potential: (q+l)*A*q
464 68 : IF (do_ewald) THEN
465 138 : ALLOCATE (epforce(3, natom))
466 46 : epforce = 0.0_dp
467 582 : dchia = -charges + qlag
468 314 : chrgx = charges
469 : CALL spme_forces(ewald_env, ewald_pw, cell, particle_set, chrgx, &
470 46 : particle_set, dchia, epforce)
471 314 : dchia = charges
472 582 : chrgx = qlag
473 : CALL spme_forces(ewald_env, ewald_pw, cell, particle_set, chrgx, &
474 46 : particle_set, dchia, epforce)
475 314 : DO iatom = 1, natom
476 268 : ikind = kind_of(iatom)
477 268 : i = atom_of_kind(iatom)
478 1118 : force(ikind)%rho_elec(:, i) = force(ikind)%rho_elec(:, i) + epforce(:, iatom)
479 : END DO
480 46 : DEALLOCATE (epforce)
481 :
482 : ! virial
483 46 : IF (use_virial) THEN
484 372 : chrgx = charges - qlag
485 24 : CALL spme_virial(ewald_env, ewald_pw, particle_set, cell, chrgx, pvir)
486 312 : virial%pv_virial = virial%pv_virial + pvir
487 372 : chrgx = qlag
488 24 : CALL spme_virial(ewald_env, ewald_pw, particle_set, cell, chrgx, pvir)
489 312 : virial%pv_virial = virial%pv_virial - pvir
490 : END IF
491 : END IF
492 :
493 : ! return Lagrange multipliers
494 416 : qlagrange(1:natom) = qlag(1:natom)
495 :
496 68 : DEALLOCATE (gab, chrgx, dchia, qlag)
497 :
498 68 : CALL timestop(handle)
499 :
500 136 : END SUBROUTINE xtb_eeq_forces
501 :
502 : ! **************************************************************************************************
503 : !> \brief ...
504 : !> \param qs_env ...
505 : !> \param dcharges ...
506 : !> \param qlagrange ...
507 : !> \param eeq_sparam ...
508 : ! **************************************************************************************************
509 58 : SUBROUTINE xtb_eeq_lagrange(qs_env, dcharges, qlagrange, eeq_sparam)
510 :
511 : TYPE(qs_environment_type), POINTER :: qs_env
512 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: dcharges
513 : REAL(KIND=dp), DIMENSION(:), INTENT(OUT) :: qlagrange
514 : TYPE(eeq_solver_type), INTENT(IN) :: eeq_sparam
515 :
516 : CHARACTER(len=*), PARAMETER :: routineN = 'xtb_eeq_lagrange'
517 :
518 : INTEGER :: handle, ikind, iunit, jkind, natom, nkind
519 58 : INTEGER, ALLOCATABLE, DIMENSION(:) :: atom_of_kind, kind_of
520 : LOGICAL :: defined, do_ewald
521 : REAL(KIND=dp) :: ala, alb, elag, gama, qlam, totalcharge
522 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: gam
523 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: gab
524 58 : REAL(KIND=dp), DIMENSION(:), POINTER :: qlag
525 58 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
526 : TYPE(cell_type), POINTER :: cell
527 : TYPE(cp_blacs_env_type), POINTER :: blacs_env
528 : TYPE(dft_control_type), POINTER :: dft_control
529 : TYPE(ewald_environment_type), POINTER :: ewald_env
530 : TYPE(ewald_pw_type), POINTER :: ewald_pw
531 : TYPE(mp_para_env_type), POINTER :: para_env
532 58 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
533 58 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
534 : TYPE(xtb_atom_type), POINTER :: xtb_atom_a, xtb_atom_b
535 : TYPE(xtb_control_type), POINTER :: xtb_control
536 :
537 58 : CALL timeset(routineN, handle)
538 :
539 58 : iunit = cp_logger_get_default_unit_nr()
540 :
541 : CALL get_qs_env(qs_env, &
542 : qs_kind_set=qs_kind_set, &
543 : atomic_kind_set=atomic_kind_set, &
544 : particle_set=particle_set, &
545 : cell=cell, &
546 58 : dft_control=dft_control)
547 58 : CALL get_qs_env(qs_env, nkind=nkind, natom=natom)
548 :
549 58 : xtb_control => dft_control%qs_control%xtb_control
550 :
551 58 : totalcharge = dft_control%charge
552 :
553 : CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, &
554 58 : atom_of_kind=atom_of_kind, kind_of=kind_of)
555 :
556 : ! gamma[a,b]
557 348 : ALLOCATE (gab(nkind, nkind), gam(nkind))
558 58 : gab = 0.0_dp
559 232 : DO ikind = 1, nkind
560 174 : CALL get_qs_kind(qs_kind_set(ikind), xtb_parameter=xtb_atom_a)
561 174 : CALL get_xtb_atom_param(xtb_atom_a, defined=defined)
562 174 : IF (.NOT. defined) CYCLE
563 174 : CALL get_xtb_atom_param(xtb_atom_a, alpg=ala, eta=gama)
564 174 : gam(ikind) = gama
565 928 : DO jkind = 1, nkind
566 522 : CALL get_qs_kind(qs_kind_set(jkind), xtb_parameter=xtb_atom_b)
567 522 : CALL get_xtb_atom_param(xtb_atom_b, defined=defined)
568 522 : IF (.NOT. defined) CYCLE
569 522 : CALL get_xtb_atom_param(xtb_atom_b, alpg=alb)
570 : !
571 1218 : gab(ikind, jkind) = SQRT(1._dp/(ala*ala + alb*alb))
572 : !
573 : END DO
574 : END DO
575 :
576 174 : ALLOCATE (qlag(natom))
577 :
578 58 : do_ewald = xtb_control%do_ewald
579 :
580 58 : CALL get_qs_env(qs_env, para_env=para_env, blacs_env=blacs_env)
581 58 : IF (do_ewald) THEN
582 : CALL get_qs_env(qs_env=qs_env, &
583 28 : ewald_env=ewald_env, ewald_pw=ewald_pw)
584 : CALL eeq_solver(qlag, qlam, elag, &
585 : particle_set, kind_of, cell, -dcharges, gam, gab, &
586 : para_env, blacs_env, dft_control, eeq_sparam, &
587 140 : ewald=do_ewald, ewald_env=ewald_env, ewald_pw=ewald_pw, iounit=iunit)
588 : ELSE
589 : CALL eeq_solver(qlag, qlam, elag, &
590 : particle_set, kind_of, cell, -dcharges, gam, gab, &
591 150 : para_env, blacs_env, dft_control, eeq_sparam, iounit=iunit)
592 : END IF
593 :
594 : ! return Lagrange multipliers
595 290 : qlagrange(1:natom) = qlag(1:natom)
596 :
597 58 : DEALLOCATE (gab, qlag)
598 :
599 58 : CALL timestop(handle)
600 :
601 116 : END SUBROUTINE xtb_eeq_lagrange
602 :
603 : END MODULE xtb_eeq
|