(git:374b731)
Loading...
Searching...
No Matches
qmmm_force.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Calculates QM/MM energy and forces
10!> \par History
11!> 2015 Factored out of force_env_methods.F
12!> \author Ole Schuett
13! **************************************************************************************************
15 USE cell_types, ONLY: cell_type
20 cp_p_file,&
35 USE kinds, ONLY: default_string_length,&
36 dp
38 USE physcon, ONLY: debye
45 USE qmmm_types, ONLY: qmmm_env_type
53#include "./base/base_uses.f90"
54
55 IMPLICIT NONE
56
57 PRIVATE
58
59 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qmmm_force'
60
62
63CONTAINS
64
65! **************************************************************************************************
66!> \brief calculates the qm/mm energy and forces
67!> \param qmmm_env ...
68!> \param calc_force if also the forces should be calculated
69!> \param consistent_energies ...
70!> \param linres ...
71!> \par History
72!> 05.2004 created [fawzi]
73!> \author Fawzi Mohamed
74! **************************************************************************************************
75 SUBROUTINE qmmm_calc_energy_force(qmmm_env, calc_force, consistent_energies, linres)
76 TYPE(qmmm_env_type), POINTER :: qmmm_env
77 LOGICAL, INTENT(IN) :: calc_force, consistent_energies, linres
78
79 CHARACTER(LEN=default_string_length) :: description, iter
80 INTEGER :: ip, j, nres, output_unit
81 INTEGER, DIMENSION(:), POINTER :: qm_atom_index
82 LOGICAL :: check, qmmm_added_chrg, qmmm_link, &
83 qmmm_link_imomm
84 REAL(kind=dp) :: energy_mm, energy_qm
85 REAL(kind=dp), DIMENSION(3) :: dip_mm, dip_qm, dip_qmmm, max_coord, &
86 min_coord
87 TYPE(cell_type), POINTER :: mm_cell, qm_cell
88 TYPE(cp_logger_type), POINTER :: logger
89 TYPE(cp_result_type), POINTER :: results_mm, results_qm, results_qmmm
90 TYPE(cp_subsys_type), POINTER :: subsys, subsys_mm, subsys_qm
91 TYPE(fist_energy_type), POINTER :: fist_energy
92 TYPE(particle_type), DIMENSION(:), POINTER :: particles_mm, particles_qm
93 TYPE(qmmm_links_type), POINTER :: qmmm_links
94 TYPE(qs_energy_type), POINTER :: qs_energy
95 TYPE(section_vals_type), POINTER :: force_env_section, print_key
96
97 min_coord = huge(0.0_dp)
98 max_coord = -huge(0.0_dp)
99 qmmm_link = .false.
100 qmmm_link_imomm = .false.
101 qmmm_added_chrg = .false.
102 logger => cp_get_default_logger()
103 output_unit = cp_logger_get_default_io_unit(logger)
104 NULLIFY (subsys_mm, subsys_qm, subsys, qm_atom_index, particles_mm, particles_qm, qm_cell, mm_cell)
105 NULLIFY (force_env_section, print_key, results_qmmm, results_qm, results_mm)
106
107 CALL get_qs_env(qmmm_env%qs_env, input=force_env_section)
108 print_key => section_vals_get_subs_vals(force_env_section, "QMMM%PRINT%DIPOLE")
109
110 cpassert(ASSOCIATED(qmmm_env))
111
112 CALL apply_qmmm_translate(qmmm_env)
113
114 CALL fist_env_get(qmmm_env%fist_env, cell=mm_cell, subsys=subsys_mm)
115 CALL get_qs_env(qmmm_env%qs_env, cell=qm_cell, cp_subsys=subsys_qm)
116 qm_atom_index => qmmm_env%qm%qm_atom_index
117 qmmm_link = qmmm_env%qm%qmmm_link
118 qmmm_links => qmmm_env%qm%qmmm_links
119 qmmm_added_chrg = (qmmm_env%qm%move_mm_charges .OR. qmmm_env%qm%add_mm_charges)
120 IF (qmmm_link) THEN
121 cpassert(ASSOCIATED(qmmm_links))
122 IF (ASSOCIATED(qmmm_links%imomm)) qmmm_link_imomm = (SIZE(qmmm_links%imomm) /= 0)
123 END IF
124 cpassert(ASSOCIATED(qm_atom_index))
125
126 particles_mm => subsys_mm%particles%els
127 particles_qm => subsys_qm%particles%els
128
129 DO j = 1, 3
130 IF (qm_cell%perd(j) == 1) cycle
131 DO ip = 1, SIZE(particles_qm)
132 check = (dot_product(qm_cell%h_inv(j, :), particles_qm(ip)%r) >= 0.0) .AND. &
133 (dot_product(qm_cell%h_inv(j, :), particles_qm(ip)%r) <= 1.0)
134 IF (output_unit > 0 .AND. .NOT. check) THEN
135 WRITE (unit=output_unit, fmt='("ip, j, pos, lat_pos ",2I6,6F12.5)') ip, j, &
136 particles_qm(ip)%r, dot_product(qm_cell%h_inv(j, :), particles_qm(ip)%r)
137 END IF
138 IF (.NOT. check) &
139 CALL cp_abort(__location__, &
140 "QM/MM QM atoms must be fully contained in the same image of the QM box "// &
141 "- No wrapping of coordinates is allowed! ")
142 END DO
143 END DO
144
145 ! If present QM/MM links (just IMOMM) correct the position of the qm-link atom
146 IF (qmmm_link_imomm) CALL qmmm_link_imomm_coord(qmmm_links, particles_qm, qm_atom_index)
147
148 ! If add charges get their position NOW!
149 IF (qmmm_added_chrg) CALL qmmm_added_chrg_coord(qmmm_env%qm, particles_mm)
150
151 ! Initialize ks_qmmm_env
152 CALL ks_qmmm_env_rebuild(qs_env=qmmm_env%qs_env, qmmm_env=qmmm_env%qm)
153
154 ! Compute the short range QM/MM Electrostatic Potential
155 CALL qmmm_el_coupling(qs_env=qmmm_env%qs_env, &
156 qmmm_env=qmmm_env%qm, &
157 mm_particles=particles_mm, &
158 mm_cell=mm_cell)
159
160 ! Fist
161 CALL fist_calc_energy_force(qmmm_env%fist_env)
162
163 ! Print Out information on fist energy calculation...
164 CALL fist_env_get(qmmm_env%fist_env, thermo=fist_energy)
165 energy_mm = fist_energy%pot
166 CALL cp_subsys_get(subsys_mm, results=results_mm)
167
168 ! QS
169 CALL qs_calc_energy_force(qmmm_env%qs_env, calc_force, consistent_energies, linres)
170
171 ! QM/MM Interaction Potential forces
172 CALL qmmm_forces(qmmm_env%qs_env, &
173 qmmm_env%qm, particles_mm, &
174 mm_cell=mm_cell, &
175 calc_force=calc_force)
176
177 ! Forces of quadratic wall on QM atoms
178 CALL apply_qmmm_walls(qmmm_env)
179
180 ! Print Out information on QS energy calculation...
181 CALL get_qs_env(qmmm_env%qs_env, energy=qs_energy)
182 energy_qm = qs_energy%total
183 CALL cp_subsys_get(subsys_qm, results=results_qm)
184
185 !TODO: is really results_qm == results_qmmm ???
186 CALL cp_subsys_get(subsys_qm, results=results_qmmm)
187
188 IF (calc_force) THEN
189 ! If present QM/MM links (just IMOMM) correct the position of the qm-link atom
190 IF (qmmm_link_imomm) CALL qmmm_link_imomm_forces(qmmm_links, particles_qm, qm_atom_index)
191 particles_mm => subsys_mm%particles%els
192 DO ip = 1, SIZE(qm_atom_index)
193 particles_mm(qm_atom_index(ip))%f = particles_mm(qm_atom_index(ip))%f + particles_qm(ip)%f
194 END DO
195 ! If add charges get rid of their derivatives right NOW!
196 IF (qmmm_added_chrg) CALL qmmm_added_chrg_forces(qmmm_env%qm, particles_mm)
197 END IF
198
199 ! Handle some output
200 output_unit = cp_print_key_unit_nr(logger, force_env_section, "QMMM%PRINT%DERIVATIVES", &
201 extension=".Log")
202 IF (output_unit > 0) THEN
203 WRITE (unit=output_unit, fmt='(/1X,A,F15.9)') "Energy after QMMM calculation: ", energy_qm
204 IF (calc_force) THEN
205 WRITE (unit=output_unit, fmt='(/1X,A)') "Derivatives on all atoms after QMMM calculation: "
206 DO ip = 1, SIZE(particles_mm)
207 WRITE (unit=output_unit, fmt='(1X,3F15.9)') particles_mm(ip)%f
208 END DO
209 END IF
210 END IF
211 CALL cp_print_key_finished_output(output_unit, logger, force_env_section, &
212 "QMMM%PRINT%DERIVATIVES")
213
214 ! Dipole
215 print_key => section_vals_get_subs_vals(force_env_section, "QMMM%PRINT%DIPOLE")
216 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), &
217 cp_p_file)) THEN
218 description = '[DIPOLE]'
219 CALL get_results(results=results_qm, description=description, n_rep=nres)
220 cpassert(nres <= 1)
221 CALL get_results(results=results_mm, description=description, n_rep=nres)
222 cpassert(nres <= 1)
223 CALL get_results(results=results_qm, description=description, values=dip_qm)
224 CALL get_results(results=results_mm, description=description, values=dip_mm)
225 dip_qmmm = dip_qm + dip_mm
226 CALL cp_results_erase(results=results_qmmm, description=description)
227 CALL put_results(results=results_qmmm, description=description, values=dip_qmmm)
228
229 output_unit = cp_print_key_unit_nr(logger, force_env_section, "QMMM%PRINT%DIPOLE", &
230 extension=".Dipole")
231 IF (output_unit > 0) THEN
232 WRITE (unit=output_unit, fmt="(A)") "QMMM TOTAL DIPOLE"
233 WRITE (unit=output_unit, fmt="(A,T31,A,T88,A)") &
234 "# iter_level", "dipole(x,y,z)[atomic units]", &
235 "dipole(x,y,z)[debye]"
236 iter = cp_iter_string(logger%iter_info)
237 WRITE (unit=output_unit, fmt="(a,6(es18.8))") &
238 iter(1:15), dip_qmmm, dip_qmmm*debye
239 END IF
240 END IF
241
242 END SUBROUTINE qmmm_calc_energy_force
243
244END MODULE qmmm_force
Handles all functions related to the CELL.
Definition cell_types.F:15
various routines to log and control the output. The idea is that decisions about where to log should ...
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
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...
character(len=default_string_length) function, public cp_iter_string(iter_info, print_key, for_file)
returns the iteration string, a string that is useful to create unique filenames (once you trim it)
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,...
integer, parameter, public cp_p_file
integer function, public cp_print_key_should_output(iteration_info, basis_section, print_key_path, used_print_key, first_time)
returns what should be done with the given property if btest(res,cp_p_store) then the property should...
set of type/routines to handle the storage of results in force_envs
subroutine, public cp_results_erase(results, description, nval)
erase a part of result_list
set of type/routines to handle the storage of results in force_envs
types that represent a subsys, i.e. a part of the system
subroutine, public cp_subsys_get(subsys, ref_count, atomic_kinds, atomic_kind_set, particles, particle_set, local_particles, molecules, molecule_set, molecule_kinds, molecule_kind_set, local_molecules, para_env, colvar_p, shell_particles, core_particles, gci, multipoles, natom, nparticle, ncore, nshell, nkind, atprop, virial, results, cell)
returns information about various attributes of the given subsys
subroutine, public fist_env_get(fist_env, atomic_kind_set, particle_set, ewald_pw, local_particles, local_molecules, molecule_kind_set, molecule_set, cell, cell_ref, ewald_env, fist_nonbond_env, thermo, para_env, subsys, qmmm, qmmm_env, input, shell_model, shell_model_ad, shell_particle_set, core_particle_set, multipoles, results, exclusions, efield)
Purpose: Get the FIST environment.
subroutine, public fist_calc_energy_force(fist_env, debug)
Calculates the total potential energy, total force, and the total pressure tensor from the potentials...
Definition fist_force.F:112
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
integer, parameter, public default_string_length
Definition kinds.F:57
Define the data structure for the particle information.
Definition of physical constants:
Definition physcon.F:68
real(kind=dp), parameter, public debye
Definition physcon.F:201
Calculates QM/MM energy and forces.
Definition qmmm_force.F:14
subroutine, public qmmm_calc_energy_force(qmmm_env, calc_force, consistent_energies, linres)
calculates the qm/mm energy and forces
Definition qmmm_force.F:76
A collection of methods to treat the QM/MM electrostatic coupling.
subroutine, public qmmm_el_coupling(qs_env, qmmm_env, mm_particles, mm_cell)
Main Driver to compute the QM/MM Electrostatic Coupling.
Routines to compute energy and forces in a QM/MM calculation.
subroutine, public qmmm_forces(qs_env, qmmm_env, mm_particles, calc_force, mm_cell)
General driver to Compute the contribution to the forces due to the QM/MM potential.
Basic container type for QM/MM.
Definition qmmm_types.F:12
subroutine, public apply_qmmm_walls(qmmm_env)
Apply QM quadratic walls in order to avoid QM atoms escaping from the QM Box.
Definition qmmm_util.F:62
subroutine, public apply_qmmm_translate(qmmm_env)
Apply translation to the full system in order to center the QM system into the QM box.
Definition qmmm_util.F:373
Perform a QUICKSTEP wavefunction optimization (single point)
Definition qs_energy.F:14
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_nonbond, sab_almo, sab_kp, sab_kp_nosym, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, ecoul_1c, rho0_s_rs, rho0_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, 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, rhs)
Get the QUICKSTEP environment.
Quickstep force driver routine.
Definition qs_force.F:12
subroutine, public qs_calc_energy_force(qs_env, calc_force, consistent_energies, linres)
...
Definition qs_force.F:107
subroutine, public ks_qmmm_env_rebuild(qs_env, qmmm_env)
Initialize the ks_qmmm_env.
Type defining parameters related to the simulation cell.
Definition cell_types.F:55
type of a logger, at the moment it contains just a print level starting at which level it should be l...
contains arbitrary information which need to be stored
represents a system: atoms, molecules, their pos,vel,...