(git:936074a)
Loading...
Searching...
No Matches
eeq_method.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 charge equilibration method
10!> \author JGH
11! **************************************************************************************************
16 USE atprop_types, ONLY: atprop_type
17 USE cell_types, ONLY: cell_type,&
18 get_cell,&
19 pbc,&
29 USE cp_fm_types, ONLY: cp_fm_create,&
37 USE eeq_data, ONLY: get_eeq_data
38 USE eeq_input, ONLY: eeq_solver_type
50 USE kinds, ONLY: dp
51 USE machine, ONLY: m_walltime
52 USE mathconstants, ONLY: oorootpi,&
53 twopi
54 USE mathlib, ONLY: invmat
58 USE physcon, ONLY: bohr
68 USE qs_kind_types, ONLY: get_qs_kind,&
82 USE spme, ONLY: spme_forces,&
86 USE virial_types, ONLY: virial_type
87#include "./base/base_uses.f90"
88
89 IMPLICIT NONE
90
91 PRIVATE
92
93 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'eeq_method'
94
95 INTEGER, PARAMETER :: maxElem = 86
96 ! covalent radii (taken from Pyykko and Atsumi, Chem. Eur. J. 15, 2009, 188-197)
97 ! values for metals decreased by 10 %
98 REAL(KIND=dp), PARAMETER :: rcov(1:maxelem) = [&
99 & 0.32_dp, 0.46_dp, 1.20_dp, 0.94_dp, 0.77_dp, 0.75_dp, 0.71_dp, 0.63_dp, &
100 & 0.64_dp, 0.67_dp, 1.40_dp, 1.25_dp, 1.13_dp, 1.04_dp, 1.10_dp, 1.02_dp, &
101 & 0.99_dp, 0.96_dp, 1.76_dp, 1.54_dp, 1.33_dp, 1.22_dp, 1.21_dp, 1.10_dp, &
102 & 1.07_dp, 1.04_dp, 1.00_dp, 0.99_dp, 1.01_dp, 1.09_dp, 1.12_dp, 1.09_dp, &
103 & 1.15_dp, 1.10_dp, 1.14_dp, 1.17_dp, 1.89_dp, 1.67_dp, 1.47_dp, 1.39_dp, &
104 & 1.32_dp, 1.24_dp, 1.15_dp, 1.13_dp, 1.13_dp, 1.08_dp, 1.15_dp, 1.23_dp, &
105 & 1.28_dp, 1.26_dp, 1.26_dp, 1.23_dp, 1.32_dp, 1.31_dp, 2.09_dp, 1.76_dp, &
106 & 1.62_dp, 1.47_dp, 1.58_dp, 1.57_dp, 1.56_dp, 1.55_dp, 1.51_dp, 1.52_dp, &
107 & 1.51_dp, 1.50_dp, 1.49_dp, 1.49_dp, 1.48_dp, 1.53_dp, 1.46_dp, 1.37_dp, &
108 & 1.31_dp, 1.23_dp, 1.18_dp, 1.16_dp, 1.11_dp, 1.12_dp, 1.13_dp, 1.32_dp, &
109 & 1.30_dp, 1.30_dp, 1.36_dp, 1.31_dp, 1.38_dp, 1.42_dp]
110
113
114CONTAINS
115
116! **************************************************************************************************
117!> \brief ...
118!> \param qs_env ...
119!> \param iounit ...
120!> \param print_level ...
121!> \param ext ...
122! **************************************************************************************************
123 SUBROUTINE eeq_print(qs_env, iounit, print_level, ext)
124
125 TYPE(qs_environment_type), POINTER :: qs_env
126 INTEGER, INTENT(IN) :: iounit, print_level
127 LOGICAL, INTENT(IN) :: ext
128
129 CHARACTER(LEN=2) :: element_symbol
130 INTEGER :: enshift_type, iatom, ikind, natom
131 REAL(kind=dp), DIMENSION(:), POINTER :: charges
132 TYPE(cell_type), POINTER :: cell
133 TYPE(eeq_solver_type) :: eeq_sparam
134 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
135
136 mark_used(print_level)
137
138 CALL get_qs_env(qs_env, natom=natom, particle_set=particle_set, cell=cell)
139 IF (ext) THEN
140 NULLIFY (charges)
141 CALL get_qs_env(qs_env, eeq=charges)
142 cpassert(ASSOCIATED(charges))
143 enshift_type = 0
144 ELSE
145 ALLOCATE (charges(natom))
146 ! enforce en shift method 1 (original/molecular)
147 ! method 2 from paper on PBC seems not to work
148 enshift_type = 1
149 !IF (ALL(cell%perd == 0)) enshift_type = 1
150 CALL eeq_charges(qs_env, charges, eeq_sparam, 2, enshift_type)
151 END IF
152
153 IF (iounit > 0) THEN
154
155 IF (enshift_type == 0) THEN
156 WRITE (unit=iounit, fmt="(/,T2,A)") "EEQ Charges (External)"
157 ELSE IF (enshift_type == 1) THEN
158 WRITE (unit=iounit, fmt="(/,T2,A)") "EEQ Charges (Parametrization 2019 (Molecules))"
159 ELSE IF (enshift_type == 2) THEN
160 WRITE (unit=iounit, fmt="(/,T2,A)") "EEQ Charges (Parametrization 2019 (Crystals))"
161 ELSE
162 cpabort("Unknown enshift_type")
163 END IF
164 WRITE (unit=iounit, fmt="(/,T2,A)") &
165 "# Atom Element Kind Atomic Charge"
166
167 DO iatom = 1, natom
168 CALL get_atomic_kind(atomic_kind=particle_set(iatom)%atomic_kind, &
169 element_symbol=element_symbol, &
170 kind_number=ikind)
171 WRITE (unit=iounit, fmt="(T4,I8,T18,A2,I10,T43,F12.4)") &
172 iatom, element_symbol, ikind, charges(iatom)
173 END DO
174
175 END IF
176
177 IF (.NOT. ext) DEALLOCATE (charges)
178
179 END SUBROUTINE eeq_print
180
181! **************************************************************************************************
182!> \brief ...
183!> \param qs_env ...
184!> \param charges ...
185!> \param eeq_sparam ...
186!> \param eeq_model ...
187!> \param enshift_type ...
188! **************************************************************************************************
189 SUBROUTINE eeq_charges(qs_env, charges, eeq_sparam, eeq_model, enshift_type)
190
191 TYPE(qs_environment_type), POINTER :: qs_env
192 REAL(kind=dp), DIMENSION(:), INTENT(INOUT) :: charges
193 TYPE(eeq_solver_type), INTENT(IN) :: eeq_sparam
194 INTEGER, INTENT(IN) :: eeq_model, enshift_type
195
196 CHARACTER(len=*), PARAMETER :: routinen = 'eeq_charges'
197
198 INTEGER :: handle, iatom, ikind, iunit, jkind, &
199 natom, nkind, za, zb
200 INTEGER, ALLOCATABLE, DIMENSION(:) :: kind_of
201 INTEGER, DIMENSION(3) :: periodic
202 LOGICAL :: do_ewald
203 REAL(kind=dp) :: ala, alb, eeq_energy, esg, kappa, &
204 lambda, scn, sgamma, totalcharge, xi
205 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: chia, cnumbers, efr, gam
206 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: gab
207 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
208 TYPE(cell_type), POINTER :: cell, cell_ref
209 TYPE(cp_blacs_env_type), POINTER :: blacs_env
210 TYPE(dcnum_type), ALLOCATABLE, DIMENSION(:) :: dcnum
211 TYPE(dft_control_type), POINTER :: dft_control
212 TYPE(ewald_environment_type), POINTER :: ewald_env
213 TYPE(ewald_pw_type), POINTER :: ewald_pw
214 TYPE(mp_para_env_type), POINTER :: para_env
215 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
216 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
217 TYPE(section_vals_type), POINTER :: ewald_section, poisson_section, &
218 print_section
219
220 CALL timeset(routinen, handle)
221
223
224 CALL get_qs_env(qs_env, &
225 qs_kind_set=qs_kind_set, &
226 atomic_kind_set=atomic_kind_set, &
227 particle_set=particle_set, &
228 para_env=para_env, &
229 blacs_env=blacs_env, &
230 cell=cell, &
231 dft_control=dft_control)
232 CALL get_qs_env(qs_env, nkind=nkind, natom=natom)
233
234 totalcharge = dft_control%charge
235
236 CALL get_cnumbers(qs_env, cnumbers, dcnum, .false.)
237
238 ! gamma[a,b]
239 ALLOCATE (gab(nkind, nkind), gam(nkind))
240 gab = 0.0_dp
241 gam = 0.0_dp
242 DO ikind = 1, nkind
243 CALL get_qs_kind(qs_kind_set(ikind), zatom=za)
244 CALL get_eeq_data(za, eeq_model, eta=gam(ikind), rad=ala)
245 DO jkind = 1, nkind
246 CALL get_qs_kind(qs_kind_set(jkind), zatom=zb)
247 CALL get_eeq_data(zb, eeq_model, rad=alb)
248 !
249 gab(ikind, jkind) = sqrt(1._dp/(ala*ala + alb*alb))
250 !
251 END DO
252 END DO
253
254 ! Chi[a,a]
255 sgamma = 8.0_dp ! see D4 for periodic systems paper
256 esg = 1.0_dp + exp(sgamma)
257 ALLOCATE (chia(natom))
258 CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, kind_of=kind_of)
259 DO iatom = 1, natom
260 ikind = kind_of(iatom)
261 CALL get_qs_kind(qs_kind_set(ikind), zatom=za)
262 CALL get_eeq_data(za, eeq_model, chi=xi, kcn=kappa)
263 !
264 IF (enshift_type == 1) THEN
265 scn = cnumbers(iatom)/sqrt(cnumbers(iatom) + 1.0e-14_dp)
266 ELSE IF (enshift_type == 2) THEN
267 scn = log(esg/(esg - cnumbers(iatom)))
268 ELSE
269 cpabort("Unknown enshift_type")
270 END IF
271 chia(iatom) = xi - kappa*scn
272 !
273 END DO
274
275 ! efield
276 IF (dft_control%apply_period_efield .OR. dft_control%apply_efield .OR. &
277 dft_control%apply_efield_field) THEN
278 ALLOCATE (efr(natom))
279 efr(1:natom) = 0.0_dp
280 CALL eeq_efield_pot(qs_env, efr)
281 chia(1:natom) = chia(1:natom) + efr(1:natom)
282 DEALLOCATE (efr)
283 END IF
284
285 CALL cnumber_release(cnumbers, dcnum, .false.)
286
287 CALL get_cell(cell, periodic=periodic)
288 do_ewald = .NOT. all(periodic == 0)
289 IF (do_ewald) THEN
290 ALLOCATE (ewald_env)
291 CALL ewald_env_create(ewald_env, para_env)
292 poisson_section => section_vals_get_subs_vals(qs_env%input, "DFT%POISSON")
293 CALL ewald_env_set(ewald_env, poisson_section=poisson_section)
294 ewald_section => section_vals_get_subs_vals(poisson_section, "EWALD")
295 print_section => section_vals_get_subs_vals(qs_env%input, "PRINT%GRID_INFORMATION")
296 CALL get_qs_env(qs_env, cell_ref=cell_ref)
297 CALL read_ewald_section_tb(ewald_env, ewald_section, cell_ref%hmat, &
298 silent=.true., pset="EEQ")
299 ALLOCATE (ewald_pw)
300 CALL ewald_pw_create(ewald_pw, ewald_env, cell, cell_ref, print_section=print_section)
301 !
302 CALL eeq_solver(charges, lambda, eeq_energy, &
303 particle_set, kind_of, cell, chia, gam, gab, &
304 para_env, blacs_env, dft_control, eeq_sparam, &
305 totalcharge=totalcharge, ewald=do_ewald, &
306 ewald_env=ewald_env, ewald_pw=ewald_pw, iounit=iunit)
307 !
308 CALL ewald_env_release(ewald_env)
309 CALL ewald_pw_release(ewald_pw)
310 DEALLOCATE (ewald_env, ewald_pw)
311 ELSE
312 CALL eeq_solver(charges, lambda, eeq_energy, &
313 particle_set, kind_of, cell, chia, gam, gab, &
314 para_env, blacs_env, dft_control, eeq_sparam, &
315 totalcharge=totalcharge, iounit=iunit)
316 END IF
317
318 DEALLOCATE (gab, gam, chia)
319
320 CALL timestop(handle)
321
322 END SUBROUTINE eeq_charges
323
324! **************************************************************************************************
325!> \brief ...
326!> \param qs_env ...
327!> \param charges ...
328!> \param dcharges ...
329!> \param gradient ...
330!> \param stress ...
331!> \param eeq_sparam ...
332!> \param eeq_model ...
333!> \param enshift_type ...
334!> \param response_only ...
335! **************************************************************************************************
336 SUBROUTINE eeq_forces(qs_env, charges, dcharges, gradient, stress, &
337 eeq_sparam, eeq_model, enshift_type, response_only)
338
339 TYPE(qs_environment_type), POINTER :: qs_env
340 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: charges, dcharges
341 REAL(kind=dp), DIMENSION(:, :), INTENT(INOUT) :: gradient
342 REAL(kind=dp), DIMENSION(3, 3), INTENT(INOUT) :: stress
343 TYPE(eeq_solver_type), INTENT(IN) :: eeq_sparam
344 INTEGER, INTENT(IN) :: eeq_model, enshift_type
345 LOGICAL, INTENT(IN) :: response_only
346
347 CHARACTER(len=*), PARAMETER :: routinen = 'eeq_forces'
348
349 INTEGER :: handle, i, ia, iatom, ikind, iunit, &
350 jatom, jkind, katom, natom, nkind, za, &
351 zb
352 INTEGER, ALLOCATABLE, DIMENSION(:) :: kind_of
353 INTEGER, DIMENSION(3) :: periodic
354 LOGICAL :: do_ewald, use_virial
355 LOGICAL, ALLOCATABLE, DIMENSION(:) :: default_present
356 REAL(kind=dp) :: ala, alb, alpha, cn, ctot, dr, dr2, drk, &
357 elag, esg, fe, gam2, gama, grc, kappa, &
358 qlam, qq, qq1, qq2, rcut, scn, sgamma, &
359 subcells, totalcharge, xi
360 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: c_radius, cnumbers, gam, qlag
361 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: epforce, gab, pair_radius
362 REAL(kind=dp), DIMENSION(3) :: fdik, ri, rij, rik, rj
363 REAL(kind=dp), DIMENSION(3, 3) :: pvir
364 REAL(kind=dp), DIMENSION(:), POINTER :: chrgx, dchia
365 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
366 TYPE(atprop_type), POINTER :: atprop
367 TYPE(cell_type), POINTER :: cell, cell_ref
368 TYPE(cp_blacs_env_type), POINTER :: blacs_env
369 TYPE(dcnum_type), ALLOCATABLE, DIMENSION(:) :: dcnum
370 TYPE(dft_control_type), POINTER :: dft_control
371 TYPE(distribution_1d_type), POINTER :: distribution_1d, local_particles
372 TYPE(distribution_2d_type), POINTER :: distribution_2d
373 TYPE(ewald_environment_type), POINTER :: ewald_env
374 TYPE(ewald_pw_type), POINTER :: ewald_pw
375 TYPE(local_atoms_type), ALLOCATABLE, DIMENSION(:) :: atom2d
376 TYPE(molecule_type), DIMENSION(:), POINTER :: molecule_set
377 TYPE(mp_para_env_type), POINTER :: para_env
379 DIMENSION(:), POINTER :: nl_iterator
380 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
381 POINTER :: sab_ew
382 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
383 TYPE(qs_force_type), DIMENSION(:), POINTER :: force
384 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
385 TYPE(section_vals_type), POINTER :: ewald_section, poisson_section, &
386 print_section
387 TYPE(virial_type), POINTER :: virial
388
389 CALL timeset(routinen, handle)
390
392
393 CALL get_qs_env(qs_env, &
394 qs_kind_set=qs_kind_set, &
395 atomic_kind_set=atomic_kind_set, &
396 particle_set=particle_set, &
397 para_env=para_env, &
398 blacs_env=blacs_env, &
399 cell=cell, &
400 force=force, &
401 virial=virial, &
402 atprop=atprop, &
403 dft_control=dft_control)
404 CALL get_qs_env(qs_env, nkind=nkind, natom=natom)
405 use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
406
407 CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, kind_of=kind_of)
408
409 totalcharge = dft_control%charge
410
411 CALL get_cnumbers(qs_env, cnumbers, dcnum, .true.)
412
413 ! gamma[a,b]
414 ALLOCATE (gab(nkind, nkind), gam(nkind))
415 gab = 0.0_dp
416 gam = 0.0_dp
417 DO ikind = 1, nkind
418 CALL get_qs_kind(qs_kind_set(ikind), zatom=za)
419 CALL get_eeq_data(za, eeq_model, eta=gam(ikind), rad=ala)
420 DO jkind = 1, nkind
421 CALL get_qs_kind(qs_kind_set(jkind), zatom=zb)
422 CALL get_eeq_data(zb, eeq_model, rad=alb)
423 !
424 gab(ikind, jkind) = sqrt(1._dp/(ala*ala + alb*alb))
425 !
426 END DO
427 END DO
428
429 ALLOCATE (qlag(natom))
430
431 CALL get_cell(cell, periodic=periodic)
432 do_ewald = .NOT. all(periodic == 0)
433 IF (do_ewald) THEN
434 ALLOCATE (ewald_env)
435 CALL ewald_env_create(ewald_env, para_env)
436 poisson_section => section_vals_get_subs_vals(qs_env%input, "DFT%POISSON")
437 CALL ewald_env_set(ewald_env, poisson_section=poisson_section)
438 ewald_section => section_vals_get_subs_vals(poisson_section, "EWALD")
439 print_section => section_vals_get_subs_vals(qs_env%input, "PRINT%GRID_INFORMATION")
440 CALL get_qs_env(qs_env, cell_ref=cell_ref)
441 CALL read_ewald_section_tb(ewald_env, ewald_section, cell_ref%hmat, &
442 silent=.true., pset="EEQ")
443 ALLOCATE (ewald_pw)
444 CALL ewald_pw_create(ewald_pw, ewald_env, cell, cell_ref, print_section=print_section)
445 !
446 CALL eeq_solver(qlag, qlam, elag, &
447 particle_set, kind_of, cell, -dcharges, gam, gab, &
448 para_env, blacs_env, dft_control, eeq_sparam, &
449 ewald=do_ewald, ewald_env=ewald_env, ewald_pw=ewald_pw, iounit=iunit)
450 ELSE
451 CALL eeq_solver(qlag, qlam, elag, &
452 particle_set, kind_of, cell, -dcharges, gam, gab, &
453 para_env, blacs_env, dft_control, eeq_sparam, iounit=iunit)
454 END IF
455
456 sgamma = 8.0_dp ! see D4 for periodic systems paper
457 esg = 1.0_dp + exp(sgamma)
458 ALLOCATE (chrgx(natom), dchia(natom))
459 DO iatom = 1, natom
460 ikind = kind_of(iatom)
461 CALL get_qs_kind(qs_kind_set(ikind), zatom=za)
462 CALL get_eeq_data(za, eeq_model, chi=xi, kcn=kappa)
463 !
464 IF (response_only) THEN
465 ctot = -0.5_dp*qlag(iatom)
466 ELSE
467 ctot = 0.5_dp*(charges(iatom) - qlag(iatom))
468 END IF
469 IF (enshift_type == 1) THEN
470 scn = sqrt(cnumbers(iatom)) + 1.0e-14_dp
471 dchia(iatom) = -ctot*kappa/scn
472 ELSE IF (enshift_type == 2) THEN
473 cn = cnumbers(iatom)
474 scn = 1.0_dp/(esg - cn)
475 dchia(iatom) = -ctot*kappa*scn
476 ELSE
477 cpabort("Unknown enshift_type")
478 END IF
479 END DO
480
481 ! Efield
482 IF (dft_control%apply_period_efield) THEN
483 CALL eeq_efield_force_periodic(qs_env, charges, qlag)
484 ELSE IF (dft_control%apply_efield) THEN
485 CALL eeq_efield_force_loc(qs_env, charges, qlag)
486 ELSE IF (dft_control%apply_efield_field) THEN
487 cpabort("apply field")
488 END IF
489
490 ! Forces from q*X
491 CALL get_qs_env(qs_env=qs_env, local_particles=local_particles)
492 DO ikind = 1, nkind
493 DO ia = 1, local_particles%n_el(ikind)
494 iatom = local_particles%list(ikind)%array(ia)
495 DO i = 1, dcnum(iatom)%neighbors
496 katom = dcnum(iatom)%nlist(i)
497 rik = dcnum(iatom)%rik(:, i)
498 drk = sqrt(sum(rik(:)**2))
499 IF (drk > 1.e-3_dp) THEN
500 fdik(:) = dchia(iatom)*dcnum(iatom)%dvals(i)*rik(:)/drk
501 gradient(:, iatom) = gradient(:, iatom) - fdik(:)
502 gradient(:, katom) = gradient(:, katom) + fdik(:)
503 IF (use_virial) THEN
504 CALL virial_pair_force(stress, 1._dp, fdik, rik)
505 END IF
506 END IF
507 END DO
508 END DO
509 END DO
510
511 ! Forces from (0.5*q+l)*dA/dR*q
512 IF (do_ewald) THEN
513
514 ! Build the neighbor lists for the CN
515 CALL get_qs_env(qs_env, &
516 distribution_2d=distribution_2d, &
517 local_particles=distribution_1d, &
518 molecule_set=molecule_set)
519 subcells = 2.0_dp
520 CALL ewald_env_get(ewald_env, alpha=alpha, rcut=rcut)
521 rcut = 2.0_dp*rcut
522 NULLIFY (sab_ew)
523 ALLOCATE (c_radius(nkind), default_present(nkind), pair_radius(nkind, nkind))
524 c_radius(:) = rcut
525 default_present = .true.
526 ALLOCATE (atom2d(nkind))
527 CALL atom2d_build(atom2d, distribution_1d, distribution_2d, atomic_kind_set, &
528 molecule_set, .false., particle_set=particle_set)
529 CALL pair_radius_setup(default_present, default_present, c_radius, c_radius, pair_radius)
530 CALL build_neighbor_lists(sab_ew, particle_set, atom2d, cell, pair_radius, &
531 subcells=subcells, operator_type="PP", nlname="sab_ew")
532 DEALLOCATE (c_radius, pair_radius, default_present)
533 CALL atom2d_cleanup(atom2d)
534 !
535 CALL neighbor_list_iterator_create(nl_iterator, sab_ew)
536 DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
537 CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, &
538 iatom=iatom, jatom=jatom, r=rij)
539 !
540 dr2 = sum(rij**2)
541 dr = sqrt(dr2)
542 IF (dr > rcut .OR. dr < 1.e-6_dp) cycle
543 fe = 1.0_dp
544 IF (iatom == jatom) fe = 0.5_dp
545 IF (response_only) THEN
546 qq = -qlag(iatom)*charges(jatom)
547 ELSE
548 qq = (0.5_dp*charges(iatom) - qlag(iatom))*charges(jatom)
549 END IF
550 gama = gab(ikind, jkind)
551 gam2 = gama*gama
552 grc = 2._dp*gama*exp(-gam2*dr2)*oorootpi/dr - erf(gama*dr)/dr2 &
553 - 2._dp*alpha*exp(-alpha**2*dr2)*oorootpi/dr + erf(alpha*dr)/dr2
554 IF (response_only) THEN
555 qq1 = -qlag(iatom)*charges(jatom)
556 qq2 = -qlag(jatom)*charges(iatom)
557 ELSE
558 qq1 = (0.5_dp*charges(iatom) - qlag(iatom))*charges(jatom)
559 qq2 = (0.5_dp*charges(jatom) - qlag(jatom))*charges(iatom)
560 END IF
561 fdik(:) = -qq1*grc*rij(:)/dr
562 gradient(:, iatom) = gradient(:, iatom) + fdik(:)
563 gradient(:, jatom) = gradient(:, jatom) - fdik(:)
564 IF (use_virial) THEN
565 CALL virial_pair_force(stress, -fe, fdik, rij)
566 END IF
567 fdik(:) = qq2*grc*rij(:)/dr
568 gradient(:, iatom) = gradient(:, iatom) - fdik(:)
569 gradient(:, jatom) = gradient(:, jatom) + fdik(:)
570 IF (use_virial) THEN
571 CALL virial_pair_force(stress, fe, fdik, rij)
572 END IF
573 END DO
574 CALL neighbor_list_iterator_release(nl_iterator)
575 !
576 CALL release_neighbor_list_sets(sab_ew)
577 ELSE
578 DO ikind = 1, nkind
579 DO ia = 1, local_particles%n_el(ikind)
580 iatom = local_particles%list(ikind)%array(ia)
581 ri(1:3) = particle_set(iatom)%r(1:3)
582 DO jatom = 1, natom
583 IF (iatom == jatom) cycle
584 jkind = kind_of(jatom)
585 IF (response_only) THEN
586 qq = -qlag(iatom)*charges(jatom)
587 ELSE
588 qq = (0.5_dp*charges(iatom) - qlag(iatom))*charges(jatom)
589 END IF
590 rj(1:3) = particle_set(jatom)%r(1:3)
591 rij(1:3) = ri(1:3) - rj(1:3)
592 rij = pbc(rij, cell)
593 dr2 = sum(rij**2)
594 dr = sqrt(dr2)
595 gama = gab(ikind, jkind)
596 gam2 = gama*gama
597 grc = 2._dp*gama*exp(-gam2*dr2)*oorootpi/dr - erf(gama*dr)/dr2
598 fdik(:) = qq*grc*rij(:)/dr
599 gradient(:, iatom) = gradient(:, iatom) + fdik(:)
600 gradient(:, jatom) = gradient(:, jatom) - fdik(:)
601 END DO
602 END DO
603 END DO
604 END IF
605
606 ! Forces from Ewald potential: (q+l)*A*q
607 IF (do_ewald) THEN
608 ALLOCATE (epforce(3, natom))
609 epforce = 0.0_dp
610 IF (response_only) THEN
611 dchia(1:natom) = qlag(1:natom)
612 ELSE
613 dchia(1:natom) = -charges(1:natom) + qlag(1:natom)
614 END IF
615 chrgx(1:natom) = charges(1:natom)
616 CALL spme_forces(ewald_env, ewald_pw, cell, particle_set, chrgx, &
617 particle_set, dchia, epforce)
618 dchia(1:natom) = charges(1:natom)
619 chrgx(1:natom) = qlag(1:natom)
620 CALL spme_forces(ewald_env, ewald_pw, cell, particle_set, chrgx, &
621 particle_set, dchia, epforce)
622 gradient(1:3, 1:natom) = gradient(1:3, 1:natom) + epforce(1:3, 1:natom)
623 DEALLOCATE (epforce)
624
625 ! virial
626 IF (use_virial) THEN
627 chrgx(1:natom) = charges(1:natom) - qlag(1:natom)
628 CALL spme_virial(ewald_env, ewald_pw, particle_set, cell, chrgx, pvir)
629 stress = stress - pvir
630 chrgx(1:natom) = qlag(1:natom)
631 CALL spme_virial(ewald_env, ewald_pw, particle_set, cell, chrgx, pvir)
632 stress = stress + pvir
633 IF (response_only) THEN
634 chrgx(1:natom) = charges(1:natom)
635 CALL spme_virial(ewald_env, ewald_pw, particle_set, cell, chrgx, pvir)
636 stress = stress + pvir
637 END IF
638 END IF
639 !
640 CALL ewald_env_release(ewald_env)
641 CALL ewald_pw_release(ewald_pw)
642 DEALLOCATE (ewald_env, ewald_pw)
643 END IF
644
645 CALL cnumber_release(cnumbers, dcnum, .true.)
646
647 DEALLOCATE (gab, gam, qlag, chrgx, dchia)
648
649 CALL timestop(handle)
650
651 END SUBROUTINE eeq_forces
652
653! **************************************************************************************************
654!> \brief ...
655!> \param qs_env ...
656!> \param cnumbers ...
657!> \param dcnum ...
658!> \param calculate_forces ...
659! **************************************************************************************************
660 SUBROUTINE get_cnumbers(qs_env, cnumbers, dcnum, calculate_forces)
661
662 TYPE(qs_environment_type), POINTER :: qs_env
663 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: cnumbers
664 TYPE(dcnum_type), ALLOCATABLE, DIMENSION(:) :: dcnum
665 LOGICAL, INTENT(IN) :: calculate_forces
666
667 INTEGER :: ikind, natom, nkind, za
668 LOGICAL, ALLOCATABLE, DIMENSION(:) :: default_present
669 REAL(kind=dp) :: subcells
670 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: c_radius
671 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: pair_radius
672 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
673 TYPE(cell_type), POINTER :: cell
674 TYPE(distribution_1d_type), POINTER :: distribution_1d
675 TYPE(distribution_2d_type), POINTER :: distribution_2d
676 TYPE(local_atoms_type), ALLOCATABLE, DIMENSION(:) :: atom2d
677 TYPE(molecule_type), DIMENSION(:), POINTER :: molecule_set
678 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
679 POINTER :: sab_cn
680 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
681 TYPE(qs_dispersion_type), POINTER :: disp
682 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
683
684 CALL get_qs_env(qs_env, &
685 qs_kind_set=qs_kind_set, &
686 atomic_kind_set=atomic_kind_set, &
687 particle_set=particle_set, &
688 cell=cell, &
689 distribution_2d=distribution_2d, &
690 local_particles=distribution_1d, &
691 molecule_set=molecule_set)
692 CALL get_qs_env(qs_env, nkind=nkind, natom=natom)
693
694 ! Check for dispersion_env and sab_cn needed for cnumbers
695 ALLOCATE (disp)
696 disp%k1 = 16.0_dp
697 disp%k2 = 4._dp/3._dp
698 disp%eps_cn = 1.e-6_dp
699 disp%max_elem = maxelem
700 ALLOCATE (disp%rcov(maxelem))
701 disp%rcov(1:maxelem) = bohr*disp%k2*rcov(1:maxelem)
702 subcells = 2.0_dp
703 ! Build the neighbor lists for the CN
704 NULLIFY (sab_cn)
705 ALLOCATE (c_radius(nkind), default_present(nkind), pair_radius(nkind, nkind))
706 c_radius(:) = 0.0_dp
707 default_present = .true.
708 DO ikind = 1, nkind
709 CALL get_atomic_kind(atomic_kind_set(ikind), z=za)
710 c_radius(ikind) = 4._dp*rcov(za)*bohr
711 END DO
712 ALLOCATE (atom2d(nkind))
713 CALL atom2d_build(atom2d, distribution_1d, distribution_2d, atomic_kind_set, &
714 molecule_set, .false., particle_set=particle_set)
715 CALL pair_radius_setup(default_present, default_present, c_radius, c_radius, pair_radius)
716 CALL build_neighbor_lists(sab_cn, particle_set, atom2d, cell, pair_radius, &
717 subcells=subcells, operator_type="PP", nlname="sab_cn")
718 disp%sab_cn => sab_cn
719 DEALLOCATE (c_radius, pair_radius, default_present)
720 CALL atom2d_cleanup(atom2d)
721
722 ! Calculate coordination numbers
723 CALL cnumber_init(qs_env, cnumbers, dcnum, 2, calculate_forces, disp_env=disp)
724
725 CALL qs_dispersion_release(disp)
726
727 END SUBROUTINE get_cnumbers
728
729! **************************************************************************************************
730!> \brief ...
731!> \param charges ...
732!> \param lambda ...
733!> \param eeq_energy ...
734!> \param particle_set ...
735!> \param kind_of ...
736!> \param cell ...
737!> \param chia ...
738!> \param gam ...
739!> \param gab ...
740!> \param para_env ...
741!> \param blacs_env ...
742!> \param dft_control ...
743!> \param eeq_sparam ...
744!> \param totalcharge ...
745!> \param ewald ...
746!> \param ewald_env ...
747!> \param ewald_pw ...
748!> \param iounit ...
749! **************************************************************************************************
750 SUBROUTINE eeq_solver(charges, lambda, eeq_energy, particle_set, kind_of, cell, &
751 chia, gam, gab, para_env, blacs_env, dft_control, eeq_sparam, &
752 totalcharge, ewald, ewald_env, ewald_pw, iounit)
753
754 REAL(kind=dp), DIMENSION(:), INTENT(INOUT) :: charges
755 REAL(kind=dp), INTENT(INOUT) :: lambda, eeq_energy
756 TYPE(particle_type), DIMENSION(:), INTENT(IN) :: particle_set
757 INTEGER, DIMENSION(:), INTENT(IN) :: kind_of
758 TYPE(cell_type), POINTER :: cell
759 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: chia, gam
760 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: gab
761 TYPE(mp_para_env_type), POINTER :: para_env
762 TYPE(cp_blacs_env_type), POINTER :: blacs_env
763 TYPE(dft_control_type), POINTER :: dft_control
764 TYPE(eeq_solver_type), INTENT(IN) :: eeq_sparam
765 REAL(kind=dp), INTENT(IN), OPTIONAL :: totalcharge
766 LOGICAL, INTENT(IN), OPTIONAL :: ewald
767 TYPE(ewald_environment_type), OPTIONAL, POINTER :: ewald_env
768 TYPE(ewald_pw_type), OPTIONAL, POINTER :: ewald_pw
769 INTEGER, INTENT(IN), OPTIONAL :: iounit
770
771 CHARACTER(len=*), PARAMETER :: routinen = 'eeq_solver'
772
773 INTEGER :: handle, ierror, iunit, natom, nkind, ns
774 LOGICAL :: do_direct, do_displ, do_ewald, do_sparse
775 REAL(kind=dp) :: alpha, deth, ftime, qtot
776 TYPE(cp_fm_struct_type), POINTER :: mat_struct
777 TYPE(cp_fm_type) :: eeq_mat
778
779 CALL timeset(routinen, handle)
780
781 do_ewald = .false.
782 IF (PRESENT(ewald)) do_ewald = ewald
783 !
784 qtot = 0.0_dp
785 IF (PRESENT(totalcharge)) qtot = totalcharge
786 !
787 iunit = -1
788 IF (PRESENT(iounit)) iunit = iounit
789
790 ! EEQ solver parameters
791 do_direct = eeq_sparam%direct
792 do_sparse = eeq_sparam%sparse
793
794 do_displ = .false.
795 IF (dft_control%apply_period_efield .AND. ASSOCIATED(dft_control%period_efield)) THEN
796 do_displ = dft_control%period_efield%displacement_field
797 END IF
798
799 ! sparse option NYA
800 IF (do_sparse) THEN
801 CALL cp_abort(__location__, "EEQ: Sparse option not yet available")
802 END IF
803 !
804 natom = SIZE(particle_set)
805 nkind = SIZE(gam)
806 ns = natom + 1
807 CALL cp_fm_struct_create(mat_struct, context=blacs_env, para_env=para_env, &
808 nrow_global=ns, ncol_global=ns)
809 CALL cp_fm_create(eeq_mat, mat_struct)
810 CALL cp_fm_set_all(eeq_mat, 0.0_dp, 0.0_dp)
811 !
812 IF (do_ewald) THEN
813 cpassert(PRESENT(ewald_env))
814 cpassert(PRESENT(ewald_pw))
815 IF (do_direct) THEN
816 IF (do_displ) THEN
817 cpabort("NYA")
818 ELSE
819 CALL fpbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
820 kind_of, cell, chia, gam, gab, qtot, &
821 ewald_env, ewald_pw, iounit)
822 END IF
823 ELSE
824 IF (do_displ) THEN
825 cpabort("NYA")
826 ELSE
827 ierror = 0
828 CALL pbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
829 kind_of, cell, chia, gam, gab, qtot, &
830 ewald_env, ewald_pw, eeq_sparam, ierror, iounit)
831 IF (ierror /= 0) THEN
832 ! backup to non-iterative method
833 CALL fpbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
834 kind_of, cell, chia, gam, gab, qtot, &
835 ewald_env, ewald_pw, iounit)
836 END IF
837 END IF
838 END IF
839 IF (qtot /= 0._dp) THEN
840 CALL get_cell(cell=cell, deth=deth)
841 CALL ewald_env_get(ewald_env, alpha=alpha)
842 eeq_energy = eeq_energy - 0.5_dp*qtot**2/alpha**2/deth
843 END IF
844 ELSE
845 CALL mi_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, kind_of, &
846 cell, chia, gam, gab, qtot, ftime)
847 IF (iounit > 0) THEN
848 WRITE (iunit, '(A,T67,F14.3)') " EEQ| Molecular solver time[s]", ftime
849 END IF
850 END IF
851 CALL cp_fm_struct_release(mat_struct)
852 CALL cp_fm_release(eeq_mat)
853
854 CALL timestop(handle)
855
856 END SUBROUTINE eeq_solver
857
858! **************************************************************************************************
859!> \brief ...
860!> \param charges ...
861!> \param lambda ...
862!> \param eeq_energy ...
863!> \param eeq_mat ...
864!> \param particle_set ...
865!> \param kind_of ...
866!> \param cell ...
867!> \param chia ...
868!> \param gam ...
869!> \param gab ...
870!> \param qtot ...
871!> \param ftime ...
872! **************************************************************************************************
873 SUBROUTINE mi_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, kind_of, cell, &
874 chia, gam, gab, qtot, ftime)
875
876 REAL(kind=dp), DIMENSION(:), INTENT(INOUT) :: charges
877 REAL(kind=dp), INTENT(INOUT) :: lambda, eeq_energy
878 TYPE(cp_fm_type) :: eeq_mat
879 TYPE(particle_type), DIMENSION(:), INTENT(IN) :: particle_set
880 INTEGER, DIMENSION(:), INTENT(IN) :: kind_of
881 TYPE(cell_type), POINTER :: cell
882 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: chia, gam
883 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: gab
884 REAL(kind=dp), INTENT(IN) :: qtot
885 REAL(kind=dp), INTENT(OUT) :: ftime
886
887 CHARACTER(len=*), PARAMETER :: routinen = 'mi_solver'
888
889 INTEGER :: handle, ia, iac, iar, ic, ikind, ir, &
890 jkind, natom, ncloc, ncvloc, nkind, &
891 nrloc, nrvloc, ns
892 INTEGER, DIMENSION(:), POINTER :: cind, cvind, rind, rvind
893 REAL(kind=dp) :: dr, grc, te, ti, xr
894 REAL(kind=dp), DIMENSION(3) :: ri, rij, rj
895 TYPE(cp_fm_struct_type), POINTER :: mat_struct, vec_struct
896 TYPE(cp_fm_type) :: rhs_vec
897 TYPE(mp_para_env_type), POINTER :: para_env
898
899 CALL timeset(routinen, handle)
900 ti = m_walltime()
901
902 natom = SIZE(particle_set)
903 nkind = SIZE(gam)
904 !
905 ns = natom + 1
906 CALL cp_fm_get_info(eeq_mat, matrix_struct=mat_struct, para_env=para_env)
907 CALL cp_fm_get_info(eeq_mat, nrow_local=nrloc, ncol_local=ncloc, &
908 row_indices=rind, col_indices=cind)
909 CALL cp_fm_struct_create(vec_struct, template_fmstruct=mat_struct, &
910 nrow_global=ns, ncol_global=1)
911 CALL cp_fm_create(rhs_vec, vec_struct)
912 CALL cp_fm_get_info(rhs_vec, nrow_local=nrvloc, ncol_local=ncvloc, &
913 row_indices=rvind, col_indices=cvind)
914 !
915 ! set up matrix
916 CALL cp_fm_set_all(eeq_mat, 1.0_dp, 0.0_dp)
917 CALL cp_fm_set_all(rhs_vec, 0.0_dp)
918 DO ir = 1, nrloc
919 iar = rind(ir)
920 IF (iar > natom) cycle
921 ikind = kind_of(iar)
922 ri(1:3) = particle_set(iar)%r(1:3)
923 DO ic = 1, ncloc
924 iac = cind(ic)
925 IF (iac > natom) cycle
926 jkind = kind_of(iac)
927 rj(1:3) = particle_set(iac)%r(1:3)
928 IF (iar == iac) THEN
929 grc = gam(ikind) + 2.0_dp*gab(ikind, ikind)*oorootpi
930 ELSE
931 rij(1:3) = ri(1:3) - rj(1:3)
932 rij = pbc(rij, cell)
933 dr = sqrt(sum(rij**2))
934 grc = erf(gab(ikind, jkind)*dr)/dr
935 END IF
936 eeq_mat%local_data(ir, ic) = grc
937 END DO
938 END DO
939 ! set up rhs vector
940 DO ir = 1, nrvloc
941 iar = rvind(ir)
942 DO ic = 1, ncvloc
943 iac = cvind(ic)
944 ia = max(iar, iac)
945 IF (ia > natom) THEN
946 xr = qtot
947 ELSE
948 xr = -chia(ia)
949 END IF
950 rhs_vec%local_data(ir, ic) = xr
951 END DO
952 END DO
953 !
954 CALL cp_fm_solve(eeq_mat, rhs_vec)
955 !
956 charges = 0.0_dp
957 lambda = 0.0_dp
958 DO ir = 1, nrvloc
959 iar = rvind(ir)
960 DO ic = 1, ncvloc
961 iac = cvind(ic)
962 ia = max(iar, iac)
963 IF (ia <= natom) THEN
964 xr = rhs_vec%local_data(ir, ic)
965 charges(ia) = xr
966 ELSE
967 lambda = rhs_vec%local_data(ir, ic)
968 END IF
969 END DO
970 END DO
971 CALL para_env%sum(lambda)
972 CALL para_env%sum(charges)
973 !
974 ! energy: 0.5*(q^T.X - lambda*totalcharge)
975 eeq_energy = 0.5*sum(charges(1:natom)*chia(1:natom)) - 0.5_dp*lambda*qtot
976
977 CALL cp_fm_struct_release(vec_struct)
978 CALL cp_fm_release(rhs_vec)
979
980 te = m_walltime()
981 ftime = te - ti
982 CALL timestop(handle)
983
984 END SUBROUTINE mi_solver
985
986! **************************************************************************************************
987!> \brief ...
988!> \param charges ...
989!> \param lambda ...
990!> \param eeq_energy ...
991!> \param eeq_mat ...
992!> \param particle_set ...
993!> \param kind_of ...
994!> \param cell ...
995!> \param chia ...
996!> \param gam ...
997!> \param gab ...
998!> \param qtot ...
999!> \param ewald_env ...
1000!> \param ewald_pw ...
1001!> \param eeq_sparam ...
1002!> \param ierror ...
1003!> \param iounit ...
1004! **************************************************************************************************
1005 SUBROUTINE pbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
1006 kind_of, cell, chia, gam, gab, qtot, &
1007 ewald_env, ewald_pw, eeq_sparam, ierror, iounit)
1008
1009 REAL(kind=dp), DIMENSION(:), INTENT(INOUT) :: charges
1010 REAL(kind=dp), INTENT(INOUT) :: lambda, eeq_energy
1011 TYPE(cp_fm_type) :: eeq_mat
1012 TYPE(particle_type), DIMENSION(:), INTENT(IN) :: particle_set
1013 INTEGER, DIMENSION(:), INTENT(IN) :: kind_of
1014 TYPE(cell_type), POINTER :: cell
1015 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: chia, gam
1016 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: gab
1017 REAL(kind=dp), INTENT(IN) :: qtot
1018 TYPE(ewald_environment_type), POINTER :: ewald_env
1019 TYPE(ewald_pw_type), POINTER :: ewald_pw
1020 TYPE(eeq_solver_type), INTENT(IN) :: eeq_sparam
1021 INTEGER, INTENT(OUT) :: ierror
1022 INTEGER, OPTIONAL :: iounit
1023
1024 CHARACTER(len=*), PARAMETER :: routinen = 'pbc_solver'
1025
1026 INTEGER :: ewald_type, handle, i, iac, iar, ic, ikind, info, ir, iunit, iv, ix, iy, iz, &
1027 jkind, max_diis, mdiis, natom, ncloc, ndiis, nkind, now, nrloc, ns, sdiis
1028 INTEGER, DIMENSION(3) :: cvec, ncell, periodic
1029 INTEGER, DIMENSION(:), POINTER :: cind, rind
1030 REAL(kind=dp) :: ad, alpha, astep, deth, dr, eeqn, &
1031 eps_diis, ftime, grc1, grc2, rcut, &
1032 res, resin, rmax, te, ti
1033 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: bvec, dvec
1034 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: dmat, fvec, vmat, xvec
1035 REAL(kind=dp), DIMENSION(3) :: ri, rij, rijl, rj
1036 REAL(kind=dp), DIMENSION(3, 3) :: hmat
1037 REAL(kind=dp), DIMENSION(:), POINTER :: rhs, rv0, xv0
1038 TYPE(cp_fm_struct_type), POINTER :: mat_struct
1039 TYPE(cp_fm_type) :: mmat, pmat
1040 TYPE(mp_para_env_type), POINTER :: para_env
1041
1042 CALL timeset(routinen, handle)
1043 ti = m_walltime()
1044
1045 ierror = 0
1046
1047 iunit = -1
1048 IF (PRESENT(iounit)) iunit = iounit
1049
1050 natom = SIZE(particle_set)
1051 nkind = SIZE(gam)
1052 !
1053 CALL get_cell(cell=cell, deth=deth)
1054 CALL ewald_env_get(ewald_env, alpha=alpha, rcut=rcut, ewald_type=ewald_type)
1055 ad = 2.0_dp*alpha*oorootpi
1056 IF (ewald_type /= do_ewald_spme) THEN
1057 CALL cp_abort(__location__, "Only SPME Ewald method available with EEQ.")
1058 END IF
1059 !
1060 rmax = 2.0_dp*rcut
1061 ! max cells used
1062 CALL get_cell(cell, h=hmat, periodic=periodic)
1063 ncell(1) = ceiling(rmax/plane_distance(1, 0, 0, cell))
1064 ncell(2) = ceiling(rmax/plane_distance(0, 1, 0, cell))
1065 ncell(3) = ceiling(rmax/plane_distance(0, 0, 1, cell))
1066 IF (periodic(1) == 0) ncell(1) = 0
1067 IF (periodic(2) == 0) ncell(2) = 0
1068 IF (periodic(3) == 0) ncell(3) = 0
1069 !
1070 CALL mi_solver(charges, lambda, eeqn, eeq_mat, particle_set, kind_of, cell, &
1071 chia, gam, gab, qtot, ftime)
1072 IF (iunit > 0) THEN
1073 WRITE (iunit, '(A,T67,F14.3)') " EEQ| Iterative PBC guess time[s]", ftime
1074 END IF
1075 CALL cp_fm_get_info(eeq_mat, matrix_struct=mat_struct, para_env=para_env)
1076 CALL cp_fm_create(pmat, mat_struct)
1077 CALL cp_fm_create(mmat, mat_struct)
1078 !
1079 ! response matrix
1080 CALL cp_fm_get_info(eeq_mat, nrow_local=nrloc, ncol_local=ncloc, &
1081 row_indices=rind, col_indices=cind)
1082 CALL cp_fm_set_all(eeq_mat, 0.0_dp, 0.0_dp)
1083 DO ir = 1, nrloc
1084 iar = rind(ir)
1085 ri = 0.0_dp
1086 IF (iar <= natom) THEN
1087 ikind = kind_of(iar)
1088 ri(1:3) = particle_set(iar)%r(1:3)
1089 END IF
1090 DO ic = 1, ncloc
1091 iac = cind(ic)
1092 IF (iac > natom .AND. iar > natom) THEN
1093 eeq_mat%local_data(ir, ic) = 0.0_dp
1094 cycle
1095 ELSE IF ((iac > natom) .OR. (iar > natom)) THEN
1096 eeq_mat%local_data(ir, ic) = 1.0_dp
1097 cycle
1098 END IF
1099 jkind = kind_of(iac)
1100 rj(1:3) = particle_set(iac)%r(1:3)
1101 rij(1:3) = ri(1:3) - rj(1:3)
1102 rij = pbc(rij, cell)
1103 DO ix = -ncell(1), ncell(1)
1104 DO iy = -ncell(2), ncell(2)
1105 DO iz = -ncell(3), ncell(3)
1106 cvec = [ix, iy, iz]
1107 rijl = rij + matmul(hmat, cvec)
1108 dr = sqrt(sum(rijl**2))
1109 IF (dr > rmax) cycle
1110 IF (iar == iac .AND. dr < 0.00001_dp) THEN
1111 grc1 = gam(ikind) + 2.0_dp*gab(ikind, ikind)*oorootpi - ad
1112 ELSE
1113 grc1 = erf(gab(ikind, jkind)*dr)/dr - erf(alpha*dr)/dr
1114 END IF
1115 eeq_mat%local_data(ir, ic) = eeq_mat%local_data(ir, ic) + grc1
1116 END DO
1117 END DO
1118 END DO
1119 END DO
1120 END DO
1121 !
1122 ! preconditioner
1123 CALL cp_fm_get_info(pmat, nrow_local=nrloc, ncol_local=ncloc, &
1124 row_indices=rind, col_indices=cind)
1125 CALL cp_fm_set_all(pmat, 0.0_dp, 0.0_dp)
1126 DO ir = 1, nrloc
1127 iar = rind(ir)
1128 ri = 0.0_dp
1129 IF (iar <= natom) THEN
1130 ikind = kind_of(iar)
1131 ri(1:3) = particle_set(iar)%r(1:3)
1132 END IF
1133 DO ic = 1, ncloc
1134 iac = cind(ic)
1135 IF (iac > natom .AND. iar > natom) THEN
1136 pmat%local_data(ir, ic) = 0.0_dp
1137 cycle
1138 ELSE IF ((iac > natom) .OR. (iar > natom)) THEN
1139 pmat%local_data(ir, ic) = 1.0_dp
1140 cycle
1141 END IF
1142 jkind = kind_of(iac)
1143 rj(1:3) = particle_set(iac)%r(1:3)
1144 rij(1:3) = ri(1:3) - rj(1:3)
1145 rij = pbc(rij, cell)
1146 IF (iar == iac) THEN
1147 grc2 = gam(ikind) + 2.0_dp*gab(ikind, ikind)*oorootpi
1148 ELSE
1149 grc2 = erf(gab(ikind, jkind)*dr)/dr
1150 END IF
1151 pmat%local_data(ir, ic) = grc2
1152 END DO
1153 END DO
1154 CALL cp_fm_set_all(mmat, 0.0_dp, 0.0_dp)
1155 ! preconditioner invers
1156 CALL cp_fm_invert(pmat, mmat)
1157 !
1158 ! rhs
1159 ns = natom + 1
1160 ALLOCATE (rhs(ns))
1161 rhs(1:natom) = chia(1:natom)
1162 rhs(ns) = -qtot
1163 !
1164 ALLOCATE (xv0(ns), rv0(ns))
1165 ! initial guess
1166 xv0(1:natom) = charges(1:natom)
1167 xv0(ns) = 0.0_dp
1168 ! DIIS optimizer
1169 max_diis = eeq_sparam%max_diis
1170 mdiis = eeq_sparam%mdiis
1171 sdiis = eeq_sparam%sdiis
1172 eps_diis = eeq_sparam%eps_diis
1173 astep = eeq_sparam%alpha
1174 ALLOCATE (xvec(ns, mdiis), fvec(ns, mdiis), bvec(ns))
1175 xvec = 0.0_dp; fvec = 0.0_dp
1176 ALLOCATE (vmat(mdiis, mdiis), dmat(mdiis + 1, mdiis + 1), dvec(mdiis + 1))
1177 dmat = 0.0_dp; dvec = 0.0_dp
1178 ndiis = 1
1179 now = 1
1180 CALL get_energy_gradient(eeqn, eeq_mat, mmat, ewald_env, ewald_pw, &
1181 cell, particle_set, xv0, rhs, rv0)
1182 resin = sqrt(sum(rv0*rv0))
1183 !
1184 DO iv = 1, max_diis
1185 res = sqrt(sum(rv0*rv0))
1186 IF (res > 10._dp*resin) EXIT
1187 IF (res < eps_diis) EXIT
1188 !
1189 now = mod(iv - 1, mdiis) + 1
1190 ndiis = min(iv, mdiis)
1191 xvec(1:ns, now) = xv0(1:ns)
1192 fvec(1:ns, now) = rv0(1:ns)
1193 DO i = 1, ndiis
1194 vmat(now, i) = sum(fvec(:, now)*fvec(:, i))
1195 vmat(i, now) = vmat(now, i)
1196 END DO
1197 IF (ndiis < sdiis) THEN
1198 xv0(1:ns) = xv0(1:ns) + astep*rv0(1:ns)
1199 ELSE
1200 dvec = 0.0_dp
1201 dvec(ndiis + 1) = 1.0_dp
1202 dmat(1:ndiis, 1:ndiis) = vmat(1:ndiis, 1:ndiis)
1203 dmat(ndiis + 1, 1:ndiis) = 1.0_dp
1204 dmat(1:ndiis, ndiis + 1) = 1.0_dp
1205 dmat(ndiis + 1, ndiis + 1) = 0.0_dp
1206 CALL invmat(dmat(1:ndiis + 1, 1:ndiis + 1), info)
1207 dvec(1:ndiis + 1) = matmul(dmat(1:ndiis + 1, 1:ndiis + 1), dvec(1:ndiis + 1))
1208 xv0(1:ns) = matmul(xvec(1:ns, 1:ndiis), dvec(1:ndiis))
1209 xv0(1:ns) = xv0(1:ns) + matmul(fvec(1:ns, 1:ndiis), dvec(1:ndiis))
1210 END IF
1211 !
1212 CALL get_energy_gradient(eeqn, eeq_mat, mmat, ewald_env, ewald_pw, &
1213 cell, particle_set, xv0, rhs, rv0)
1214 END DO
1215 charges(1:natom) = xv0(1:natom)
1216 lambda = xv0(ns)
1217 eeq_energy = eeqn
1218 IF (res > eps_diis) ierror = 1
1219 !
1220 DEALLOCATE (xvec, fvec, bvec)
1221 DEALLOCATE (vmat, dmat, dvec)
1222 DEALLOCATE (xv0, rv0)
1223 DEALLOCATE (rhs)
1224 CALL cp_fm_release(pmat)
1225 CALL cp_fm_release(mmat)
1226
1227 te = m_walltime()
1228 IF (iunit > 0) THEN
1229 IF (ierror == 1) THEN
1230 WRITE (iunit, '(A)') " EEQ| PBC solver failed to converge "
1231 ELSE
1232 WRITE (iunit, '(A,T50,I4,T61,E20.5)') " EEQ| PBC solver: iterations/accuracy ", iv, res
1233 END IF
1234 WRITE (iunit, '(A,T67,F14.3)') " EEQ| Iterative PBC solver: time[s]", te - ti
1235 END IF
1236 CALL timestop(handle)
1237
1238 END SUBROUTINE pbc_solver
1239
1240! **************************************************************************************************
1241!> \brief ...
1242!> \param charges ...
1243!> \param lambda ...
1244!> \param eeq_energy ...
1245!> \param eeq_mat ...
1246!> \param particle_set ...
1247!> \param kind_of ...
1248!> \param cell ...
1249!> \param chia ...
1250!> \param gam ...
1251!> \param gab ...
1252!> \param qtot ...
1253!> \param ewald_env ...
1254!> \param ewald_pw ...
1255!> \param iounit ...
1256! **************************************************************************************************
1257 SUBROUTINE fpbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
1258 kind_of, cell, chia, gam, gab, qtot, ewald_env, ewald_pw, iounit)
1259
1260 REAL(kind=dp), DIMENSION(:), INTENT(INOUT) :: charges
1261 REAL(kind=dp), INTENT(INOUT) :: lambda, eeq_energy
1262 TYPE(cp_fm_type) :: eeq_mat
1263 TYPE(particle_type), DIMENSION(:), INTENT(IN) :: particle_set
1264 INTEGER, DIMENSION(:), INTENT(IN) :: kind_of
1265 TYPE(cell_type), POINTER :: cell
1266 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: chia, gam
1267 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: gab
1268 REAL(kind=dp), INTENT(IN) :: qtot
1269 TYPE(ewald_environment_type), POINTER :: ewald_env
1270 TYPE(ewald_pw_type), POINTER :: ewald_pw
1271 INTEGER, INTENT(IN), OPTIONAL :: iounit
1272
1273 CHARACTER(len=*), PARAMETER :: routinen = 'fpbc_solver'
1274
1275 INTEGER :: ewald_type, handle, ia, iac, iar, ic, &
1276 ikind, ir, iunit, ix, iy, iz, jkind, &
1277 natom, ncloc, ncvloc, nkind, nrloc, &
1278 nrvloc, ns
1279 INTEGER, DIMENSION(3) :: cvec, ncell, periodic
1280 INTEGER, DIMENSION(:), POINTER :: cind, cvind, rind, rvind
1281 REAL(kind=dp) :: ad, alpha, deth, dr, grc1, rcut, rmax, &
1282 te, ti, xr
1283 REAL(kind=dp), DIMENSION(3) :: ri, rij, rijl, rj
1284 REAL(kind=dp), DIMENSION(3, 3) :: hmat
1285 REAL(kind=dp), DIMENSION(:), POINTER :: pval, xval
1286 TYPE(cp_fm_struct_type), POINTER :: mat_struct, vec_struct
1287 TYPE(cp_fm_type) :: rhs_vec
1288 TYPE(mp_para_env_type), POINTER :: para_env
1289
1290 CALL timeset(routinen, handle)
1291 ti = m_walltime()
1292
1293 iunit = -1
1294 IF (PRESENT(iounit)) iunit = iounit
1295
1296 natom = SIZE(particle_set)
1297 nkind = SIZE(gam)
1298 ns = natom + 1
1299 !
1300 CALL get_cell(cell=cell, deth=deth)
1301 CALL ewald_env_get(ewald_env, alpha=alpha, rcut=rcut, ewald_type=ewald_type)
1302 ad = 2.0_dp*alpha*oorootpi
1303 IF (ewald_type /= do_ewald_spme) THEN
1304 CALL cp_abort(__location__, "Only SPME Ewald method available with EEQ.")
1305 END IF
1306 !
1307 rmax = 2.0_dp*rcut
1308 ! max cells used
1309 CALL get_cell(cell, h=hmat, periodic=periodic)
1310 ncell(1) = ceiling(rmax/plane_distance(1, 0, 0, cell))
1311 ncell(2) = ceiling(rmax/plane_distance(0, 1, 0, cell))
1312 ncell(3) = ceiling(rmax/plane_distance(0, 0, 1, cell))
1313 IF (periodic(1) == 0) ncell(1) = 0
1314 IF (periodic(2) == 0) ncell(2) = 0
1315 IF (periodic(3) == 0) ncell(3) = 0
1316 !
1317 CALL cp_fm_get_info(eeq_mat, matrix_struct=mat_struct, para_env=para_env)
1318 CALL cp_fm_set_all(eeq_mat, 0.0_dp, 0.0_dp)
1319 CALL cp_fm_get_info(eeq_mat, nrow_local=nrloc, ncol_local=ncloc, &
1320 row_indices=rind, col_indices=cind)
1321 CALL cp_fm_struct_create(vec_struct, template_fmstruct=mat_struct, &
1322 nrow_global=ns, ncol_global=1)
1323 CALL cp_fm_create(rhs_vec, vec_struct)
1324 CALL cp_fm_get_info(rhs_vec, nrow_local=nrvloc, ncol_local=ncvloc, &
1325 row_indices=rvind, col_indices=cvind)
1326 ! response matrix
1327 DO ir = 1, nrloc
1328 iar = rind(ir)
1329 ri = 0.0_dp
1330 IF (iar <= natom) THEN
1331 ikind = kind_of(iar)
1332 ri(1:3) = particle_set(iar)%r(1:3)
1333 END IF
1334 DO ic = 1, ncloc
1335 iac = cind(ic)
1336 IF (iac > natom .AND. iar > natom) THEN
1337 eeq_mat%local_data(ir, ic) = 0.0_dp
1338 cycle
1339 ELSE IF ((iac > natom) .OR. (iar > natom)) THEN
1340 eeq_mat%local_data(ir, ic) = 1.0_dp
1341 cycle
1342 END IF
1343 jkind = kind_of(iac)
1344 rj(1:3) = particle_set(iac)%r(1:3)
1345 rij(1:3) = ri(1:3) - rj(1:3)
1346 rij = pbc(rij, cell)
1347 DO ix = -ncell(1), ncell(1)
1348 DO iy = -ncell(2), ncell(2)
1349 DO iz = -ncell(3), ncell(3)
1350 cvec = [ix, iy, iz]
1351 rijl = rij + matmul(hmat, cvec)
1352 dr = sqrt(sum(rijl**2))
1353 IF (dr > rmax) cycle
1354 IF (iar == iac .AND. dr < 0.0001_dp) THEN
1355 grc1 = gam(ikind) + 2.0_dp*gab(ikind, ikind)*oorootpi - ad
1356 ELSE
1357 grc1 = erf(gab(ikind, jkind)*dr)/dr - erf(alpha*dr)/dr
1358 END IF
1359 eeq_mat%local_data(ir, ic) = eeq_mat%local_data(ir, ic) + grc1
1360 END DO
1361 END DO
1362 END DO
1363 END DO
1364 END DO
1365 !
1366 ALLOCATE (xval(natom), pval(natom))
1367 DO ia = 1, natom
1368 xval = 0.0_dp
1369 xval(ia) = 1.0_dp
1370 CALL apply_potential(ewald_env, ewald_pw, cell, particle_set, xval, pval)
1371 !
1372 DO ir = 1, nrloc
1373 iar = rind(ir)
1374 IF (iar /= ia) cycle
1375 DO ic = 1, ncloc
1376 iac = cind(ic)
1377 IF (iac > natom) cycle
1378 eeq_mat%local_data(ir, ic) = eeq_mat%local_data(ir, ic) + pval(iac)
1379 END DO
1380 END DO
1381 END DO
1382 DEALLOCATE (xval, pval)
1383 !
1384 ! set up rhs vector
1385 DO ir = 1, nrvloc
1386 iar = rvind(ir)
1387 DO ic = 1, ncvloc
1388 iac = cvind(ic)
1389 ia = max(iar, iac)
1390 IF (ia > natom) THEN
1391 xr = qtot
1392 ELSE
1393 xr = -chia(ia)
1394 END IF
1395 rhs_vec%local_data(ir, ic) = xr
1396 END DO
1397 END DO
1398 !
1399 CALL cp_fm_solve(eeq_mat, rhs_vec)
1400 !
1401 charges = 0.0_dp
1402 lambda = 0.0_dp
1403 DO ir = 1, nrvloc
1404 iar = rvind(ir)
1405 DO ic = 1, ncvloc
1406 iac = cvind(ic)
1407 ia = max(iar, iac)
1408 IF (ia <= natom) THEN
1409 xr = rhs_vec%local_data(ir, ic)
1410 charges(ia) = xr
1411 ELSE
1412 lambda = rhs_vec%local_data(ir, ic)
1413 END IF
1414 END DO
1415 END DO
1416 CALL para_env%sum(lambda)
1417 CALL para_env%sum(charges)
1418 !
1419 ! energy: 0.5*(q^T.X - lambda*totalcharge)
1420 eeq_energy = 0.5*sum(charges(1:natom)*chia(1:natom)) - 0.5_dp*lambda*qtot
1421
1422 CALL cp_fm_struct_release(vec_struct)
1423 CALL cp_fm_release(rhs_vec)
1424
1425 te = m_walltime()
1426 IF (iunit > 0) THEN
1427 WRITE (iunit, '(A,T67,F14.3)') " EEQ| Direct PBC solver: time[s]", te - ti
1428 END IF
1429 CALL timestop(handle)
1430
1431 END SUBROUTINE fpbc_solver
1432
1433! **************************************************************************************************
1434!> \brief ...
1435!> \param ewald_env ...
1436!> \param ewald_pw ...
1437!> \param cell ...
1438!> \param particle_set ...
1439!> \param charges ...
1440!> \param potential ...
1441! **************************************************************************************************
1442 SUBROUTINE apply_potential(ewald_env, ewald_pw, cell, particle_set, charges, potential)
1443 TYPE(ewald_environment_type), POINTER :: ewald_env
1444 TYPE(ewald_pw_type), POINTER :: ewald_pw
1445 TYPE(cell_type), POINTER :: cell
1446 TYPE(particle_type), DIMENSION(:), INTENT(IN) :: particle_set
1447 REAL(kind=dp), DIMENSION(:), INTENT(IN), POINTER :: charges
1448 REAL(kind=dp), DIMENSION(:), INTENT(INOUT) :: potential
1449
1450 TYPE(mp_para_env_type), POINTER :: para_env
1451
1452 CALL ewald_env_get(ewald_env, para_env=para_env)
1453 potential = 0.0_dp
1454 CALL spme_potential(ewald_env, ewald_pw, cell, particle_set, charges, &
1455 particle_set, potential)
1456 CALL para_env%sum(potential)
1457
1458 END SUBROUTINE apply_potential
1459
1460! **************************************************************************************************
1461!> \brief ...
1462!> \param eeqn ...
1463!> \param fm_mat ...
1464!> \param mmat ...
1465!> \param ewald_env ...
1466!> \param ewald_pw ...
1467!> \param cell ...
1468!> \param particle_set ...
1469!> \param charges ...
1470!> \param rhs ...
1471!> \param potential ...
1472! **************************************************************************************************
1473 SUBROUTINE get_energy_gradient(eeqn, fm_mat, mmat, ewald_env, ewald_pw, &
1474 cell, particle_set, charges, rhs, potential)
1475 REAL(kind=dp), INTENT(INOUT) :: eeqn
1476 TYPE(cp_fm_type), INTENT(IN) :: fm_mat, mmat
1477 TYPE(ewald_environment_type), POINTER :: ewald_env
1478 TYPE(ewald_pw_type), POINTER :: ewald_pw
1479 TYPE(cell_type), POINTER :: cell
1480 TYPE(particle_type), DIMENSION(:), INTENT(IN) :: particle_set
1481 REAL(kind=dp), DIMENSION(:), INTENT(IN), POINTER :: charges
1482 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: rhs
1483 REAL(kind=dp), DIMENSION(:), INTENT(INOUT) :: potential
1484
1485 INTEGER :: na, ns
1486 REAL(kind=dp) :: lambda
1487 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: mvec
1488 TYPE(mp_para_env_type), POINTER :: para_env
1489
1490 ns = SIZE(charges)
1491 na = ns - 1
1492 CALL ewald_env_get(ewald_env, para_env=para_env)
1493 potential = 0.0_dp
1494 CALL spme_potential(ewald_env, ewald_pw, cell, particle_set, charges(1:na), &
1495 particle_set, potential(1:na))
1496 CALL para_env%sum(potential(1:na))
1497 CALL cp_fm_matvec(fm_mat, charges, potential, alpha=1.0_dp, beta=1.0_dp)
1498 eeqn = 0.5_dp*sum(charges(1:na)*potential(1:na)) + sum(charges(1:na)*rhs(1:na))
1499 potential(1:ns) = potential(1:ns) + rhs(1:ns)
1500 ALLOCATE (mvec(ns))
1501 CALL cp_fm_matvec(mmat, potential, mvec, alpha=-1.0_dp, beta=0.0_dp)
1502 lambda = -sum(mvec(1:na))/real(na, kind=dp)
1503 potential(1:na) = mvec(1:na) + lambda
1504 DEALLOCATE (mvec)
1505
1506 END SUBROUTINE get_energy_gradient
1507
1508! **************************************************************************************************
1509!> \brief ...
1510!> \param qs_env ...
1511!> \param charges ...
1512!> \param ef_energy ...
1513! **************************************************************************************************
1514 SUBROUTINE eeq_efield_energy(qs_env, charges, ef_energy)
1515 TYPE(qs_environment_type), POINTER :: qs_env
1516 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: charges
1517 REAL(kind=dp), INTENT(OUT) :: ef_energy
1518
1519 COMPLEX(KIND=dp) :: zdeta
1520 COMPLEX(KIND=dp), DIMENSION(3) :: zi
1521 INTEGER :: ia, idir, natom
1522 LOGICAL :: dfield
1523 REAL(kind=dp) :: kr, omega, q
1524 REAL(kind=dp), DIMENSION(3) :: ci, dfilter, fieldpol, fpolvec, kvec, &
1525 qi, ria
1526 REAL(kind=dp), DIMENSION(3, 3) :: hmat
1527 TYPE(cell_type), POINTER :: cell
1528 TYPE(dft_control_type), POINTER :: dft_control
1529 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1530
1531 CALL get_qs_env(qs_env, natom=natom, dft_control=dft_control)
1532 CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set)
1533
1534 IF (dft_control%apply_period_efield) THEN
1535 dfield = dft_control%period_efield%displacement_field
1536
1537 IF (ALLOCATED(dft_control%period_efield%strength_list)) THEN
1538 cpabort("use of strength_list not implemented for eeq_efield_energy")
1539 END IF
1540
1541 fieldpol = dft_control%period_efield%polarisation
1542 fieldpol = fieldpol/sqrt(dot_product(fieldpol, fieldpol))
1543 fieldpol = -fieldpol*dft_control%period_efield%strength
1544 hmat = cell%hmat(:, :)/twopi
1545 DO idir = 1, 3
1546 fpolvec(idir) = fieldpol(1)*hmat(1, idir) + fieldpol(2)*hmat(2, idir) &
1547 + fieldpol(3)*hmat(3, idir)
1548 END DO
1549
1550 zi(:) = cmplx(1._dp, 0._dp, dp)
1551 DO ia = 1, natom
1552 q = charges(ia)
1553 ria = particle_set(ia)%r
1554 ria = pbc(ria, cell)
1555 DO idir = 1, 3
1556 kvec(:) = twopi*cell%h_inv(idir, :)
1557 kr = sum(kvec(:)*ria(:))
1558 zdeta = cmplx(cos(kr), sin(kr), kind=dp)**q
1559 zi(idir) = zi(idir)*zdeta
1560 END DO
1561 END DO
1562 qi = aimag(log(zi))
1563 IF (dfield) THEN
1564 dfilter(1:3) = dft_control%period_efield%d_filter(1:3)
1565 omega = cell%deth
1566 ci = matmul(hmat, qi)/omega
1567 ef_energy = 0.0_dp
1568 DO idir = 1, 3
1569 ef_energy = ef_energy + dfilter(idir)*(fieldpol(idir) - 2._dp*twopi*ci(idir))**2
1570 END DO
1571 ef_energy = -0.25_dp*omega/twopi*ef_energy
1572 ELSE
1573 ef_energy = sum(fpolvec(:)*qi(:))
1574 END IF
1575
1576 ELSE IF (dft_control%apply_efield) THEN
1577
1578 fieldpol = dft_control%efield_fields(1)%efield%polarisation* &
1579 dft_control%efield_fields(1)%efield%strength
1580
1581 ef_energy = 0.0_dp
1582 DO ia = 1, natom
1583 ria = particle_set(ia)%r
1584 ria = pbc(ria, cell)
1585 q = charges(ia)
1586 ef_energy = ef_energy - q*sum(fieldpol*ria)
1587 END DO
1588
1589 ELSE
1590 cpabort("apply field")
1591 END IF
1592
1593 END SUBROUTINE eeq_efield_energy
1594
1595! **************************************************************************************************
1596!> \brief ...
1597!> \param qs_env ...
1598!> \param efr ...
1599! **************************************************************************************************
1600 SUBROUTINE eeq_efield_pot(qs_env, efr)
1601 TYPE(qs_environment_type), POINTER :: qs_env
1602 REAL(kind=dp), DIMENSION(:), INTENT(INOUT) :: efr
1603
1604 INTEGER :: ia, idir, natom
1605 LOGICAL :: dfield
1606 REAL(kind=dp) :: kr
1607 REAL(kind=dp), DIMENSION(3) :: fieldpol, fpolvec, kvec, ria
1608 REAL(kind=dp), DIMENSION(3, 3) :: hmat
1609 TYPE(cell_type), POINTER :: cell
1610 TYPE(dft_control_type), POINTER :: dft_control
1611 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1612
1613 CALL get_qs_env(qs_env, natom=natom, dft_control=dft_control)
1614 CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set)
1615
1616 IF (dft_control%apply_period_efield) THEN
1617 dfield = dft_control%period_efield%displacement_field
1618
1619 IF (ALLOCATED(dft_control%period_efield%strength_list)) THEN
1620 cpabort("use of strength_list not implemented for eeq_efield_pot")
1621 END IF
1622
1623 fieldpol = dft_control%period_efield%polarisation
1624 fieldpol = fieldpol/sqrt(dot_product(fieldpol, fieldpol))
1625 fieldpol = -fieldpol*dft_control%period_efield%strength
1626 hmat = cell%hmat(:, :)/twopi
1627 DO idir = 1, 3
1628 fpolvec(idir) = fieldpol(1)*hmat(1, idir) + fieldpol(2)*hmat(2, idir) &
1629 + fieldpol(3)*hmat(3, idir)
1630 END DO
1631
1632 IF (dfield) THEN
1633 ! dE/dq depends on q, postpone calculation
1634 efr = 0.0_dp
1635 ELSE
1636 efr = 0.0_dp
1637 DO ia = 1, natom
1638 ria = particle_set(ia)%r
1639 ria = pbc(ria, cell)
1640 DO idir = 1, 3
1641 kvec(:) = twopi*cell%h_inv(idir, :)
1642 kr = sum(kvec(:)*ria(:))
1643 efr(ia) = efr(ia) + kr*fpolvec(idir)
1644 END DO
1645 END DO
1646 END IF
1647
1648 ELSE IF (dft_control%apply_efield) THEN
1649
1650 fieldpol = dft_control%efield_fields(1)%efield%polarisation* &
1651 dft_control%efield_fields(1)%efield%strength
1652
1653 DO ia = 1, natom
1654 ria = particle_set(ia)%r
1655 ria = pbc(ria, cell)
1656 efr(ia) = -sum(fieldpol*ria)
1657 END DO
1658
1659 ELSE
1660 cpabort("apply field")
1661 END IF
1662
1663 END SUBROUTINE eeq_efield_pot
1664
1665! **************************************************************************************************
1666!> \brief ...
1667!> \param charges ...
1668!> \param dft_control ...
1669!> \param particle_set ...
1670!> \param cell ...
1671!> \param efr ...
1672! **************************************************************************************************
1673 SUBROUTINE eeq_dfield_pot(charges, dft_control, particle_set, cell, efr)
1674 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: charges
1675 TYPE(dft_control_type), POINTER :: dft_control
1676 TYPE(particle_type), DIMENSION(:), INTENT(IN) :: particle_set
1677 TYPE(cell_type), POINTER :: cell
1678 REAL(kind=dp), DIMENSION(:), INTENT(INOUT) :: efr
1679
1680 COMPLEX(KIND=dp) :: zdeta
1681 COMPLEX(KIND=dp), DIMENSION(3) :: zi
1682 INTEGER :: ia, idir, natom
1683 REAL(kind=dp) :: kr, omega, q
1684 REAL(kind=dp), DIMENSION(3) :: ci, dfilter, fieldpol, kvec, qi, ria
1685 REAL(kind=dp), DIMENSION(3, 3) :: hmat
1686
1687 natom = SIZE(particle_set)
1688
1689 IF (ALLOCATED(dft_control%period_efield%strength_list)) THEN
1690 cpabort("use of strength_list not implemented for eeq_dfield_pot")
1691 END IF
1692
1693 dfilter(1:3) = dft_control%period_efield%d_filter(1:3)
1694 fieldpol = dft_control%period_efield%polarisation
1695 fieldpol = fieldpol/sqrt(dot_product(fieldpol, fieldpol))
1696 fieldpol = -fieldpol*dft_control%period_efield%strength
1697 hmat = cell%hmat(:, :)/twopi
1698 omega = cell%deth
1699 !
1700 zi(:) = cmplx(1._dp, 0._dp, dp)
1701 DO ia = 1, natom
1702 q = charges(ia)
1703 ria = particle_set(ia)%r
1704 ria = pbc(ria, cell)
1705 DO idir = 1, 3
1706 kvec(:) = twopi*cell%h_inv(idir, :)
1707 kr = sum(kvec(:)*ria(:))
1708 zdeta = cmplx(cos(kr), sin(kr), kind=dp)**q
1709 zi(idir) = zi(idir)*zdeta
1710 END DO
1711 END DO
1712 qi = aimag(log(zi))
1713 ci = matmul(hmat, qi)/omega
1714 ci = dfilter*(fieldpol - 2._dp*twopi*ci)
1715 DO ia = 1, natom
1716 ria = particle_set(ia)%r
1717 ria = pbc(ria, cell)
1718 efr(ia) = efr(ia) - sum(ci*ria)
1719 END DO
1720
1721 END SUBROUTINE eeq_dfield_pot
1722
1723! **************************************************************************************************
1724!> \brief ...
1725!> \param qs_env ...
1726!> \param charges ...
1727!> \param qlag ...
1728! **************************************************************************************************
1729 SUBROUTINE eeq_efield_force_loc(qs_env, charges, qlag)
1730 TYPE(qs_environment_type), POINTER :: qs_env
1731 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: charges, qlag
1732
1733 INTEGER :: atom_a, ia, iatom, ikind, natom, nkind
1734 INTEGER, ALLOCATABLE, DIMENSION(:) :: atom_of_kind
1735 REAL(kind=dp) :: q
1736 REAL(kind=dp), DIMENSION(3) :: fieldpol
1737 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
1738 TYPE(cell_type), POINTER :: cell
1739 TYPE(dft_control_type), POINTER :: dft_control
1740 TYPE(distribution_1d_type), POINTER :: local_particles
1741 TYPE(mp_para_env_type), POINTER :: para_env
1742 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1743 TYPE(qs_force_type), DIMENSION(:), POINTER :: force
1744
1745 CALL get_qs_env(qs_env=qs_env, &
1746 dft_control=dft_control, &
1747 cell=cell, particle_set=particle_set, &
1748 nkind=nkind, natom=natom, &
1749 para_env=para_env, &
1750 local_particles=local_particles)
1751
1752 fieldpol = dft_control%efield_fields(1)%efield%polarisation* &
1753 dft_control%efield_fields(1)%efield%strength
1754
1755 CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set)
1756 CALL get_atomic_kind_set(atomic_kind_set, atom_of_kind=atom_of_kind)
1757 CALL get_qs_env(qs_env=qs_env, force=force)
1758
1759 DO ikind = 1, nkind
1760 force(ikind)%efield = 0.0_dp
1761 DO ia = 1, local_particles%n_el(ikind)
1762 iatom = local_particles%list(ikind)%array(ia)
1763 q = charges(iatom) - qlag(iatom)
1764 atom_a = atom_of_kind(iatom)
1765 force(ikind)%efield(1:3, atom_a) = -q*fieldpol(1:3)
1766 END DO
1767 CALL para_env%sum(force(ikind)%efield)
1768 END DO
1769
1770 END SUBROUTINE eeq_efield_force_loc
1771
1772! **************************************************************************************************
1773!> \brief ...
1774!> \param qs_env ...
1775!> \param charges ...
1776!> \param qlag ...
1777! **************************************************************************************************
1778 SUBROUTINE eeq_efield_force_periodic(qs_env, charges, qlag)
1779 TYPE(qs_environment_type), POINTER :: qs_env
1780 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: charges, qlag
1781
1782 INTEGER :: atom_a, ia, iatom, ikind, natom, nkind
1783 INTEGER, ALLOCATABLE, DIMENSION(:) :: atom_of_kind
1784 LOGICAL :: dfield, use_virial
1785 REAL(kind=dp) :: q
1786 REAL(kind=dp), DIMENSION(3) :: fa, fieldpol, ria
1787 REAL(kind=dp), DIMENSION(3, 3) :: pve
1788 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
1789 TYPE(cell_type), POINTER :: cell
1790 TYPE(dft_control_type), POINTER :: dft_control
1791 TYPE(distribution_1d_type), POINTER :: local_particles
1792 TYPE(mp_para_env_type), POINTER :: para_env
1793 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1794 TYPE(qs_force_type), DIMENSION(:), POINTER :: force
1795 TYPE(virial_type), POINTER :: virial
1796
1797 CALL get_qs_env(qs_env=qs_env, &
1798 dft_control=dft_control, &
1799 cell=cell, particle_set=particle_set, &
1800 virial=virial, &
1801 nkind=nkind, natom=natom, &
1802 para_env=para_env, &
1803 local_particles=local_particles)
1804
1805 dfield = dft_control%period_efield%displacement_field
1806 cpassert(.NOT. dfield)
1807
1808 IF (ALLOCATED(dft_control%period_efield%strength_list)) THEN
1809 cpabort("use of strength_list not implemented for eeq_efield_force_periodic")
1810 END IF
1811
1812 fieldpol = dft_control%period_efield%polarisation
1813 fieldpol = fieldpol/sqrt(dot_product(fieldpol, fieldpol))
1814 fieldpol = -fieldpol*dft_control%period_efield%strength
1815
1816 use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
1817
1818 CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set)
1819 CALL get_atomic_kind_set(atomic_kind_set, atom_of_kind=atom_of_kind)
1820 CALL get_qs_env(qs_env=qs_env, force=force)
1821
1822 pve = 0.0_dp
1823 DO ikind = 1, nkind
1824 force(ikind)%efield = 0.0_dp
1825 DO ia = 1, local_particles%n_el(ikind)
1826 iatom = local_particles%list(ikind)%array(ia)
1827 q = charges(iatom) - qlag(iatom)
1828 fa(1:3) = q*fieldpol(1:3)
1829 atom_a = atom_of_kind(iatom)
1830 force(ikind)%efield(1:3, atom_a) = fa
1831 IF (use_virial) THEN
1832 ria = particle_set(ia)%r
1833 ria = pbc(ria, cell)
1834 CALL virial_pair_force(pve, -0.5_dp, fa, ria)
1835 CALL virial_pair_force(pve, -0.5_dp, ria, fa)
1836 END IF
1837 END DO
1838 CALL para_env%sum(force(ikind)%efield)
1839 END DO
1840 virial%pv_virial = virial%pv_virial + pve
1841
1842 END SUBROUTINE eeq_efield_force_periodic
1843
1844END MODULE eeq_method
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.
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:200
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:257
methods related to the blacs parallel environment
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
Basic linear algebra operations for full matrices.
subroutine, public cp_fm_solve(matrix_a, general_a)
computes the the solution to A*b=A_general using lu decomposition
subroutine, public cp_fm_invert(matrix_a, matrix_inverse, det_a, eps_svd, eigval)
Inverts a cp_fm_type matrix, optionally returning the determinant of the input matrix.
subroutine, public cp_fm_matvec(amat, xv, yv, alpha, beta)
Calculates yv = alpha*amat*xv + beta*yv where amat: fm matrix xv : vector replicated yv : vector repl...
represent the structure of a full matrix
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
represent a full matrix distributed on many processors
Definition cp_fm_types.F:15
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp, set_zero)
creates a new full matrix with the given structure
subroutine, public cp_fm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
subroutine, public cp_fm_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
various routines to log and control the output. The idea is that decisions about where to log should ...
recursive integer function, public cp_logger_get_default_unit_nr(logger, local, skip_not_ionode)
asks the default unit number of the given logger. try to use cp_logger_get_unit_nr
stores a lists of integer that are local to a processor. The idea is that these integers represent ob...
stores a mapping of 2D info (e.g. matrix) on a 2D processor distribution (i.e. blacs grid) where cpus...
EEQ data from different sources.
Definition eeq_data.F:12
subroutine, public get_eeq_data(za, model, chi, eta, kcn, rad)
...
Definition eeq_data.F:240
Input definition and setup for EEQ model.
Definition eeq_input.F:12
Calculation of charge equilibration method.
Definition eeq_method.F:12
subroutine, public eeq_forces(qs_env, charges, dcharges, gradient, stress, eeq_sparam, eeq_model, enshift_type, response_only)
...
Definition eeq_method.F:338
subroutine, public eeq_efield_energy(qs_env, charges, ef_energy)
...
subroutine, public eeq_efield_force_periodic(qs_env, charges, qlag)
...
subroutine, public eeq_efield_pot(qs_env, efr)
...
subroutine, public eeq_charges(qs_env, charges, eeq_sparam, eeq_model, enshift_type)
...
Definition eeq_method.F:190
subroutine, public eeq_print(qs_env, iounit, print_level, ext)
...
Definition eeq_method.F:124
subroutine, public eeq_efield_force_loc(qs_env, charges, qlag)
...
subroutine, public eeq_solver(charges, lambda, eeq_energy, particle_set, kind_of, cell, chia, gam, gab, para_env, blacs_env, dft_control, eeq_sparam, totalcharge, ewald, ewald_env, ewald_pw, iounit)
...
Definition eeq_method.F:753
subroutine, public ewald_env_set(ewald_env, ewald_type, alpha, epsilon, eps_pol, gmax, ns_max, precs, o_spline, para_env, poisson_section, interaction_cutoffs, cell_hmat)
Purpose: Set the EWALD environment.
subroutine, public ewald_env_create(ewald_env, para_env)
allocates and intitializes a ewald_env
subroutine, public ewald_env_release(ewald_env)
releases the given ewald_env (see doc/ReferenceCounting.html)
subroutine, public read_ewald_section_tb(ewald_env, ewald_section, hmat, silent, pset)
Purpose: read the EWALD section for TB methods.
subroutine, public ewald_env_get(ewald_env, ewald_type, alpha, eps_pol, epsilon, gmax, ns_max, o_spline, group, para_env, poisson_section, precs, rcut, do_multipoles, max_multipole, do_ipol, max_ipol_iter, interaction_cutoffs, cell_hmat)
Purpose: Get the EWALD environment.
subroutine, public ewald_pw_release(ewald_pw)
releases the memory used by the ewald_pw
subroutine, public ewald_pw_create(ewald_pw, ewald_env, cell, cell_ref, print_section)
creates the structure ewald_pw_type
objects that represent the structure of input sections and the data contained in an input section
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Machine interface based on Fortran 2003 and POSIX.
Definition machine.F:17
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Definition machine.F:153
Definition of mathematical constants and functions.
real(kind=dp), parameter, public oorootpi
real(kind=dp), parameter, public twopi
Collection of simple mathematical functions and subroutines.
Definition mathlib.F:15
subroutine, public invmat(a, info)
returns inverse of matrix using the lapack routines DGETRF and DGETRI
Definition mathlib.F:550
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 bohr
Definition physcon.F:147
functions related to the poisson solver on regular grids
integer, parameter, public do_ewald_spme
Coordination number routines for dispersion pairpotentials.
subroutine, public cnumber_release(cnumbers, dcnum, derivatives)
...
subroutine, public cnumber_init(qs_env, cnumbers, dcnum, ftype, derivatives, disp_env)
...
Definition of disperson types for DFT calculations.
subroutine, public qs_dispersion_release(dispersion_env)
...
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, 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, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
Define the quickstep kind type and their sub types.
subroutine, public get_qs_kind(qs_kind, basis_set, basis_type, ncgf, nsgf, all_potential, tnadd_potential, gth_potential, sgp_potential, upf_potential, cneo_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zatom, zeff, elec_conf, mao, lmax_dftb, alpha_core_charge, ccore_charge, core_charge, core_charge_radius, paw_proj_set, paw_atom, hard_radius, hard0_radius, max_rad_local, covalent_radius, vdw_radius, gpw_type_forced, harmonics, max_iso_not0, max_s_harm, grid_atom, ngrid_ang, ngrid_rad, lmax_rho0, dft_plus_u_atom, l_of_dft_plus_u, n_of_dft_plus_u, u_minus_j, u_of_dft_plus_u, j_of_dft_plus_u, alpha_of_dft_plus_u, beta_of_dft_plus_u, j0_of_dft_plus_u, occupation_of_dft_plus_u, dispersion, bs_occupation, magnetization, no_optimize, addel, laddel, naddel, orbitals, max_scf, eps_scf, smear, u_ramping, u_minus_j_target, eps_u_ramping, init_u_ramping_each_scf, reltmat, ghost, monovalent, floating, name, element_symbol, pao_basis_size, pao_model_file, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
Define the neighbor list data types and the corresponding functionality.
subroutine, public release_neighbor_list_sets(nlists)
releases an array of neighbor_list_sets
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)
...
Generate the atomic neighbor lists.
subroutine, public atom2d_cleanup(atom2d)
free the internals of atom2d
subroutine, public pair_radius_setup(present_a, present_b, radius_a, radius_b, pair_radius, prmin)
...
subroutine, public build_neighbor_lists(ab_list, particle_set, atom, cell, pair_radius, subcells, mic, symmetric, molecular, subset_of_mol, current_subset, operator_type, nlname, atomb_to_keep)
Build simple pair neighbor lists.
subroutine, public atom2d_build(atom2d, distribution_1d, distribution_2d, atomic_kind_set, molecule_set, molecule_only, particle_set)
Build some distribution structure of atoms, refactored from build_qs_neighbor_lists.
Calculate the electrostatic energy by the Smooth Particle Ewald method.
Definition spme.F:14
subroutine, public spme_forces(ewald_env, ewald_pw, box, particle_set_a, charges_a, particle_set_b, charges_b, forces_b)
Calculate the forces on particles B for the electrostatic interaction betrween particles A and B.
Definition spme.F:568
subroutine, public spme_potential(ewald_env, ewald_pw, box, particle_set_a, charges_a, particle_set_b, potential)
Calculate the electrostatic potential from particles A (charge A) at positions of particles B.
Definition spme.F:427
subroutine, public spme_virial(ewald_env, ewald_pw, particle_set, box, mcharge, virial)
Internal Virial for 1/2 [rho||rho] (rho=mcharge)
Definition spme.F:719
pure subroutine, public virial_pair_force(pv_virial, f0, force, rab)
Computes the contribution to the stress tensor from two-body pair-wise forces.
Provides all information about an atomic kind.
type for the atomic properties
Type defining parameters related to the simulation cell.
Definition cell_types.F:60
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
keeps the information about the structure of a full matrix
represent a full matrix
structure to store local (to a processor) ordered lists of integers.
distributes pairs on a 2d grid of processors
stores all the informations relevant to an mpi environment
Provides all information about a quickstep kind.