40#include "./base/base_uses.f90"
44 LOGICAL,
PRIVATE :: debug_this_module = .false.
45 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'fist_pol_scf'
74 ewald_pw, fist_nonbond_env, cell, particle_set, local_particles, &
75 thermo, vg_coulomb, pot_nonbond, f_nonbond, fg_coulomb, use_virial, &
76 pv_g, pv_nonbond, mm_section, do_ipol)
87 REAL(kind=
dp) :: vg_coulomb, pot_nonbond
88 REAL(kind=
dp),
DIMENSION(:, :) :: f_nonbond, fg_coulomb
89 LOGICAL,
INTENT(IN) :: use_virial
90 REAL(kind=
dp),
DIMENSION(3, 3) :: pv_g, pv_nonbond
96 CALL fist_pol_evaluate_sc(atomic_kind_set, multipoles, ewald_env, &
97 ewald_pw, fist_nonbond_env, cell, particle_set, local_particles, &
98 thermo, vg_coulomb, pot_nonbond, f_nonbond, fg_coulomb, use_virial, &
99 pv_g, pv_nonbond, mm_section)
101 CALL fist_pol_evaluate_cg(atomic_kind_set, multipoles, ewald_env, &
102 ewald_pw, fist_nonbond_env, cell, particle_set, local_particles, &
103 thermo, vg_coulomb, pot_nonbond, f_nonbond, fg_coulomb, use_virial, &
104 pv_g, pv_nonbond, mm_section)
137 SUBROUTINE fist_pol_evaluate_sc(atomic_kind_set, multipoles, ewald_env, ewald_pw, &
138 fist_nonbond_env, cell, particle_set, local_particles, thermo, vg_coulomb, &
139 pot_nonbond, f_nonbond, fg_coulomb, use_virial, pv_g, pv_nonbond, mm_section)
150 REAL(kind=
dp) :: vg_coulomb, pot_nonbond
151 REAL(kind=
dp),
DIMENSION(:, :) :: f_nonbond, fg_coulomb
152 LOGICAL,
INTENT(IN) :: use_virial
153 REAL(kind=
dp),
DIMENSION(3, 3) :: pv_g, pv_nonbond
156 CHARACTER(len=*),
PARAMETER :: routinen =
'fist_pol_evaluate_sc'
158 INTEGER :: ewald_type, handle, i, iatom, ii, ikind, &
159 iter, iw, iw2, j, max_ipol_iter, &
160 natom_of_kind, natoms, nkind, ntot
161 INTEGER,
DIMENSION(:),
POINTER :: atom_list
163 REAL(kind=
dp) :: apol, cpol, eps_pol, pot_nonbond_local, &
165 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: efield1, efield2
169 CALL timeset(routinen, handle)
170 NULLIFY (logger, atomic_kind)
178 CALL ewald_env_get(ewald_env, max_ipol_iter=max_ipol_iter, eps_pol=eps_pol, &
179 ewald_type=ewald_type)
181 natoms =
SIZE(particle_set)
182 ALLOCATE (efield1(3, natoms))
183 ALLOCATE (efield2(9, natoms))
185 nkind =
SIZE(atomic_kind_set)
187 WRITE (iw, fmt=
'(/,T2,"POL_SCF|" ,"Method: self-consistent")')
188 WRITE (iw, fmt=
'(T2,"POL_SCF| "," Iteration",7X,"Conv.",T49,"Electrostatic & Induction Energy")')
190 pol_scf:
DO iter = 1, max_ipol_iter
192 CALL eval_pol_ewald(ewald_type, ewald_env, ewald_pw, fist_nonbond_env, cell, &
193 particle_set, local_particles, vg_coulomb, pot_nonbond_local, thermo, &
194 multipoles, do_correction_bonded=.true., do_forces=.false., &
195 do_stress=.false., do_efield=.true., iw2=iw2, do_debug=.false., &
196 atomic_kind_set=atomic_kind_set, mm_section=mm_section, &
197 efield1=efield1, efield2=efield2)
198 CALL logger%para_env%sum(pot_nonbond_local)
203 thermo%e_induction = 0.0_dp
205 atomic_kind => atomic_kind_set(ikind)
206 CALL get_atomic_kind(atomic_kind, apol=apol, cpol=cpol, natom=natom_of_kind, atom_list=atom_list)
208 IF (apol == 0 .AND. cpol == 0) cycle
210 IF (apol /= 0) ntot = ntot + natom_of_kind
211 IF (cpol /= 0) ntot = ntot + natom_of_kind
213 DO iatom = 1, natom_of_kind
214 ii = atom_list(iatom)
219 rmsd =
rmsd + (multipoles%dipoles(i, ii)/apol - efield1(i, ii))**2
223 rmsd =
rmsd + (multipoles%quadrupoles(1, 1, ii)/cpol - efield2(1, ii))**2
224 rmsd =
rmsd + (multipoles%quadrupoles(2, 1, ii)/cpol - efield2(2, ii))**2
225 rmsd =
rmsd + (multipoles%quadrupoles(3, 1, ii)/cpol - efield2(3, ii))**2
226 rmsd =
rmsd + (multipoles%quadrupoles(1, 2, ii)/cpol - efield2(4, ii))**2
227 rmsd =
rmsd + (multipoles%quadrupoles(2, 2, ii)/cpol - efield2(5, ii))**2
228 rmsd =
rmsd + (multipoles%quadrupoles(3, 2, ii)/cpol - efield2(6, ii))**2
229 rmsd =
rmsd + (multipoles%quadrupoles(1, 3, ii)/cpol - efield2(7, ii))**2
230 rmsd =
rmsd + (multipoles%quadrupoles(2, 3, ii)/cpol - efield2(8, ii))**2
231 rmsd =
rmsd + (multipoles%quadrupoles(3, 3, ii)/cpol - efield2(9, ii))**2
234 multipoles%dipoles(:, ii) = apol*efield1(:, ii)
237 multipoles%quadrupoles(1, 1, ii) = cpol*efield2(1, ii)
238 multipoles%quadrupoles(2, 1, ii) = cpol*efield2(2, ii)
239 multipoles%quadrupoles(3, 1, ii) = cpol*efield2(3, ii)
240 multipoles%quadrupoles(1, 2, ii) = cpol*efield2(4, ii)
241 multipoles%quadrupoles(2, 2, ii) = cpol*efield2(5, ii)
242 multipoles%quadrupoles(3, 2, ii) = cpol*efield2(6, ii)
243 multipoles%quadrupoles(1, 3, ii) = cpol*efield2(7, ii)
244 multipoles%quadrupoles(2, 3, ii) = cpol*efield2(8, ii)
245 multipoles%quadrupoles(3, 3, ii) = cpol*efield2(9, ii)
249 thermo%e_induction = thermo%e_induction + &
250 dot_product(multipoles%dipoles(:, ii), &
251 multipoles%dipoles(:, ii))/apol/2.0_dp
257 tmp_trace = tmp_trace + &
258 multipoles%quadrupoles(i, j, ii)*multipoles%quadrupoles(i, j, ii)
261 thermo%e_induction = thermo%e_induction + tmp_trace/cpol/6.0_dp
268 WRITE (iw, fmt=
'(T5,"POL_SCF|",5X,I5,5X,E12.6,T61,F20.10)') iter, &
269 rmsd, vg_coulomb + pot_nonbond_local + thermo%e_induction
271 IF (
rmsd <= eps_pol)
THEN
272 IF (iw > 0)
WRITE (iw, fmt=
'(T5,"POL_SCF|",1X,"Self-consistent Polarization achieved.")')
276 iwarn = ((
rmsd > eps_pol) .AND. (iter == max_ipol_iter))
277 IF (iwarn .AND. iw > 0)
WRITE (iw, fmt=
'(T5,"POL_SCF|",1X,"Self-consistent Polarization not converged!")')
278 cpwarn_if(iwarn,
"Self-consistent Polarization not converged!")
282 CALL eval_pol_ewald(ewald_type, ewald_env, ewald_pw, fist_nonbond_env, cell, &
283 particle_set, local_particles, vg_coulomb, pot_nonbond_local, thermo, &
284 multipoles, do_correction_bonded=.true., do_forces=.true., &
285 do_stress=use_virial, do_efield=.false., iw2=iw2, do_debug=.false., &
286 atomic_kind_set=atomic_kind_set, mm_section=mm_section, &
287 forces_local=fg_coulomb, forces_glob=f_nonbond, &
288 pv_local=pv_g, pv_glob=pv_nonbond)
289 pot_nonbond = pot_nonbond + pot_nonbond_local
290 CALL logger%para_env%sum(pot_nonbond_local)
294 WRITE (iw, fmt=
'(T5,"POL_SCF|",5X,"Final",T61,F20.10,/)') &
295 vg_coulomb + pot_nonbond_local + thermo%e_induction
306 CALL timestop(handle)
307 END SUBROUTINE fist_pol_evaluate_sc
350 SUBROUTINE fist_pol_evaluate_cg(atomic_kind_set, multipoles, ewald_env, ewald_pw, &
351 fist_nonbond_env, cell, particle_set, local_particles, thermo, vg_coulomb, &
352 pot_nonbond, f_nonbond, fg_coulomb, use_virial, pv_g, pv_nonbond, mm_section)
363 REAL(kind=
dp) :: vg_coulomb, pot_nonbond
364 REAL(kind=
dp),
DIMENSION(:, :) :: f_nonbond, fg_coulomb
365 LOGICAL,
INTENT(IN) :: use_virial
366 REAL(kind=
dp),
DIMENSION(3, 3) :: pv_g, pv_nonbond
369 CHARACTER(len=*),
PARAMETER :: routinen =
'fist_pol_evaluate_cg'
371 INTEGER :: ewald_type, handle, i, iatom, ii, ikind, &
372 iter, iw, iw2, max_ipol_iter, &
373 natom_of_kind, natoms, nkind, ntot
374 INTEGER,
DIMENSION(:),
POINTER :: atom_list
376 REAL(kind=
dp) :: alpha, apol, beta, denom, eps_pol, &
377 pot_nonbond_local,
rmsd
378 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: conjugate, conjugate_applied, efield1, &
379 efield1_ext, residual, tmp_dipoles
383 CALL timeset(routinen, handle)
384 NULLIFY (logger, atomic_kind)
392 CALL ewald_env_get(ewald_env, max_ipol_iter=max_ipol_iter, eps_pol=eps_pol, &
393 ewald_type=ewald_type)
396 natoms =
SIZE(particle_set)
397 ALLOCATE (efield1(3, natoms))
398 ALLOCATE (tmp_dipoles(3, natoms))
399 ALLOCATE (residual(3, natoms))
400 ALLOCATE (conjugate(3, natoms))
401 ALLOCATE (conjugate_applied(3, natoms))
402 ALLOCATE (efield1_ext(3, natoms))
407 tmp_dipoles(:, :) = multipoles%dipoles
408 multipoles%dipoles = 0.0_dp
409 CALL eval_pol_ewald(ewald_type, ewald_env, ewald_pw, fist_nonbond_env, cell, &
410 particle_set, local_particles, vg_coulomb, pot_nonbond_local, thermo, &
411 multipoles, do_correction_bonded=.true., do_forces=.false., &
412 do_stress=.false., do_efield=.true., iw2=iw2, do_debug=.false., &
413 atomic_kind_set=atomic_kind_set, mm_section=mm_section, &
415 multipoles%dipoles = tmp_dipoles
418 CALL eval_pol_ewald(ewald_type, ewald_env, ewald_pw, fist_nonbond_env, cell, &
419 particle_set, local_particles, vg_coulomb, pot_nonbond_local, thermo, &
420 multipoles, do_correction_bonded=.true., do_forces=.false., &
421 do_stress=.false., do_efield=.true., iw2=iw2, do_debug=.false., &
422 atomic_kind_set=atomic_kind_set, mm_section=mm_section, &
426 nkind =
SIZE(atomic_kind_set)
430 atomic_kind => atomic_kind_set(ikind)
431 CALL get_atomic_kind(atomic_kind, apol=apol, natom=natom_of_kind, atom_list=atom_list)
434 ntot = ntot + natom_of_kind
435 DO iatom = 1, natom_of_kind
436 ii = atom_list(iatom)
439 residual(i, ii) = efield1(i, ii) - multipoles%dipoles(i, ii)/apol
444 conjugate(:, :) = residual
447 WRITE (iw, fmt=
"(/,T2,A,T63,A)")
"POL_SCF| Method",
"conjugate gradient"
448 WRITE (iw, fmt=
"(T2,A,T26,A,T49,A)")
"POL_SCF| Iteration", &
449 "Convergence",
"Electrostatic & Induction Energy"
451 pol_scf:
DO iter = 1, max_ipol_iter
452 IF (debug_this_module)
THEN
457 CALL eval_pol_ewald(ewald_type, ewald_env, ewald_pw, fist_nonbond_env, cell, &
458 particle_set, local_particles, vg_coulomb, pot_nonbond_local, thermo, &
459 multipoles, do_correction_bonded=.true., do_forces=.false., &
460 do_stress=.false., do_efield=.true., iw2=iw2, do_debug=.false., &
461 atomic_kind_set=atomic_kind_set, mm_section=mm_section, &
469 atomic_kind => atomic_kind_set(ikind)
470 CALL get_atomic_kind(atomic_kind, apol=apol, natom=natom_of_kind, atom_list=atom_list)
473 DO iatom = 1, natom_of_kind
474 ii = atom_list(iatom)
478 IF (debug_this_module)
THEN
479 denom = denom + (residual(i, ii) - (efield1(i, ii) - &
480 multipoles%dipoles(i, ii)/apol))**2
487 WRITE (iw, fmt=
"(T2,A,T11,I9,T22,E15.6,T67,A)")
"POL_SCF|", iter,
rmsd,
"(not computed)"
488 IF (debug_this_module)
THEN
489 denom = sqrt(denom/ntot)
490 WRITE (iw, fmt=
"(T2,A,T66,E15.6)")
"POL_SCF| Error on implicit residual", denom
496 tmp_dipoles(:, :) = multipoles%dipoles
497 multipoles%dipoles = conjugate
498 CALL eval_pol_ewald(ewald_type, ewald_env, ewald_pw, fist_nonbond_env, cell, &
499 particle_set, local_particles, vg_coulomb, pot_nonbond_local, thermo, &
500 multipoles, do_correction_bonded=.true., do_forces=.false., &
501 do_stress=.false., do_efield=.true., iw2=iw2, do_debug=.false., &
502 atomic_kind_set=atomic_kind_set, mm_section=mm_section, &
503 efield1=conjugate_applied)
504 multipoles%dipoles = tmp_dipoles
505 conjugate_applied(:, :) = efield1_ext - conjugate_applied
511 atomic_kind => atomic_kind_set(ikind)
512 CALL get_atomic_kind(atomic_kind, apol=apol, natom=natom_of_kind, atom_list=atom_list)
515 DO iatom = 1, natom_of_kind
516 ii = atom_list(iatom)
518 conjugate_applied(i, ii) = conjugate_applied(i, ii) + conjugate(i, ii)/apol
520 alpha = alpha + dot_product(residual(:, ii), residual(:, ii))
521 denom = denom + dot_product(conjugate(:, ii), conjugate_applied(:, ii))
530 atomic_kind => atomic_kind_set(ikind)
531 CALL get_atomic_kind(atomic_kind, apol=apol, natom=natom_of_kind, atom_list=atom_list)
533 DO iatom = 1, natom_of_kind
534 ii = atom_list(iatom)
535 denom = denom + dot_product(residual(:, ii), residual(:, ii))
537 residual(i, ii) = residual(i, ii) - alpha*conjugate_applied(i, ii)
539 beta = beta + dot_product(residual(:, ii), residual(:, ii))
546 thermo%e_induction = 0.0_dp
548 atomic_kind => atomic_kind_set(ikind)
549 CALL get_atomic_kind(atomic_kind, apol=apol, natom=natom_of_kind, atom_list=atom_list)
552 DO iatom = 1, natom_of_kind
553 ii = atom_list(iatom)
555 multipoles%dipoles(i, ii) = multipoles%dipoles(i, ii) + alpha*conjugate(i, ii)
556 conjugate(i, ii) = residual(i, ii) + beta*conjugate(i, ii)
557 thermo%e_induction = thermo%e_induction + multipoles%dipoles(i, ii)**2/apol/2.0_dp
563 IF (
rmsd <= eps_pol)
THEN
564 IF (iw > 0)
WRITE (iw, fmt=
"(T2,A)")
"POL_SCF| Self-consistent polarization converged"
569 iwarn = ((
rmsd > eps_pol) .AND. (iter >= max_ipol_iter))
572 WRITE (iw, fmt=
"(T2,A,I0,A,ES9.3)") &
573 "POL_SCF| Self-consistent polarization not converged in ", max_ipol_iter, &
574 " steps to ", eps_pol
576 cpwarn(
"Self-consistent Polarization not converged!")
580 IF (debug_this_module)
THEN
582 CALL eval_pol_ewald(ewald_type, ewald_env, ewald_pw, fist_nonbond_env, cell, &
583 particle_set, local_particles, vg_coulomb, pot_nonbond_local, thermo, &
584 multipoles, do_correction_bonded=.true., do_forces=.true., &
585 do_stress=use_virial, do_efield=.true., iw2=iw2, do_debug=.false., &
586 atomic_kind_set=atomic_kind_set, mm_section=mm_section, &
587 forces_local=fg_coulomb, forces_glob=f_nonbond, &
588 pv_local=pv_g, pv_glob=pv_nonbond, efield1=efield1)
593 atomic_kind => atomic_kind_set(ikind)
594 CALL get_atomic_kind(atomic_kind, apol=apol, natom=natom_of_kind, atom_list=atom_list)
597 DO iatom = 1, natom_of_kind
598 ii = atom_list(iatom)
601 rmsd =
rmsd + (efield1(i, ii) - multipoles%dipoles(i, ii)/apol)**2
606 IF (iw > 0)
WRITE (iw, fmt=
"(T2,A,T66,E15.6)")
"POL_SCF| Final RMSD of residual",
rmsd
608 IF (
rmsd > eps_pol)
THEN
609 cpabort(
"Error in the conjugate gradient method for self-consistent polarization!")
613 CALL eval_pol_ewald(ewald_type, ewald_env, ewald_pw, fist_nonbond_env, cell, &
614 particle_set, local_particles, vg_coulomb, pot_nonbond_local, thermo, &
615 multipoles, do_correction_bonded=.true., do_forces=.true., &
616 do_stress=use_virial, do_efield=.false., iw2=iw2, do_debug=.false., &
617 atomic_kind_set=atomic_kind_set, mm_section=mm_section, &
618 forces_local=fg_coulomb, forces_glob=f_nonbond, &
619 pv_local=pv_g, pv_glob=pv_nonbond)
621 pot_nonbond = pot_nonbond + pot_nonbond_local
622 CALL logger%para_env%sum(pot_nonbond_local)
624 IF (iw > 0)
WRITE (iw, fmt=
"(T2,A,T61,F20.10)")
"POL_SCF| Final", &
625 vg_coulomb + pot_nonbond_local + thermo%e_induction
629 DEALLOCATE (tmp_dipoles)
630 DEALLOCATE (residual)
631 DEALLOCATE (conjugate)
632 DEALLOCATE (conjugate_applied)
633 DEALLOCATE (efield1_ext)
639 CALL timestop(handle)
641 END SUBROUTINE fist_pol_evaluate_cg
674 SUBROUTINE eval_pol_ewald(ewald_type, ewald_env, ewald_pw, fist_nonbond_env, &
675 cell, particle_set, local_particles, vg_coulomb, pot_nonbond, thermo, &
676 multipoles, do_correction_bonded, do_forces, do_stress, do_efield, iw2, &
677 do_debug, atomic_kind_set, mm_section, efield0, efield1, efield2, forces_local, &
678 forces_glob, pv_local, pv_glob)
680 INTEGER,
INTENT(IN) :: ewald_type
687 REAL(kind=
dp),
INTENT(OUT) :: vg_coulomb, pot_nonbond
690 LOGICAL,
INTENT(IN) :: do_correction_bonded, do_forces, &
692 INTEGER,
INTENT(IN) :: iw2
693 LOGICAL,
INTENT(IN) :: do_debug
696 REAL(kind=
dp),
DIMENSION(:),
OPTIONAL :: efield0
697 REAL(kind=
dp),
DIMENSION(:, :),
OPTIONAL :: efield1, efield2
698 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT), &
699 OPTIONAL :: forces_local, forces_glob, pv_local, &
702 CHARACTER(len=*),
PARAMETER :: routinen =
'eval_pol_ewald'
706 CALL timeset(routinen, handle)
710 SELECT CASE (ewald_type)
713 particle_set, local_particles, vg_coulomb, pot_nonbond, thermo%e_neut, &
714 thermo%e_self, multipoles%task, do_correction_bonded=do_correction_bonded, &
715 do_forces=do_forces, do_stress=do_stress, do_efield=do_efield, &
716 radii=multipoles%radii, charges=multipoles%charges, &
717 dipoles=multipoles%dipoles, quadrupoles=multipoles%quadrupoles, &
718 forces_local=forces_local, forces_glob=forces_glob, pv_local=pv_local, &
719 pv_glob=pv_glob, iw=iw2, do_debug=do_debug, atomic_kind_set=atomic_kind_set, &
720 mm_section=mm_section, efield0=efield0, efield1=efield1, efield2=efield2)
722 cpabort(
"Multipole Ewald not yet implemented within a PME scheme!")
724 cpabort(
"Multipole Ewald not yet implemented within a SPME scheme!")
726 CALL timestop(handle)
727 END SUBROUTINE eval_pol_ewald
Define the atomic kind types and their sub types.
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.
Handles all functions related to the CELL.
various routines to log and control the output. The idea is that decisions about where to log should ...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
stores a lists of integer that are local to a processor. The idea is that these integers represent ob...
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.
Treats the electrostatic for multipoles (up to quadrupoles)
recursive subroutine, public ewald_multipole_evaluate(ewald_env, ewald_pw, nonbond_env, cell, particle_set, local_particles, energy_local, energy_glob, e_neut, e_self, task, do_correction_bonded, do_forces, do_stress, do_efield, radii, charges, dipoles, quadrupoles, forces_local, forces_glob, pv_local, pv_glob, efield0, efield1, efield2, iw, do_debug, atomic_kind_set, mm_section)
Computes the potential and the force for a lattice sum of multipoles (up to quadrupole)
subroutine, public fist_pol_evaluate(atomic_kind_set, multipoles, ewald_env, ewald_pw, fist_nonbond_env, cell, particle_set, local_particles, thermo, vg_coulomb, pot_nonbond, f_nonbond, fg_coulomb, use_virial, pv_g, pv_nonbond, mm_section, do_ipol)
Main driver for evaluating energy/forces in a polarizable forcefield.
Defines the basic variable types.
integer, parameter, public dp
Multipole structure: for multipole (fixed and induced) in FF based MD.
Define the data structure for the particle information.
functions related to the poisson solver on regular grids
integer, parameter, public do_ewald_pme
integer, parameter, public do_ewald_ewald
integer, parameter, public do_ewald_spme
Defines functions to perform rmsd in 3D.
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
type of a logger, at the moment it contains just a print level starting at which level it should be l...
structure to store local (to a processor) ordered lists of integers.
to build arrays of pointers