Line data Source code
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 A collection of methods to treat the QM/MM electrostatic coupling
10 : !> \par History
11 : !> 5.2004 created [tlaino]
12 : !> \author Teodoro Laino
13 : ! **************************************************************************************************
14 : MODULE qmmm_gpw_energy
15 : USE cell_types, ONLY: cell_type,&
16 : pbc
17 : USE cp_control_types, ONLY: dft_control_type
18 : USE cp_log_handling, ONLY: cp_get_default_logger,&
19 : cp_logger_type
20 : USE cp_output_handling, ONLY: cp_p_file,&
21 : cp_print_key_finished_output,&
22 : cp_print_key_should_output,&
23 : cp_print_key_unit_nr
24 : USE cp_realspace_grid_cube, ONLY: cp_pw_to_cube
25 : USE cp_spline_utils, ONLY: pw_prolongate_s3,&
26 : spline3_nopbc_interp,&
27 : spline3_pbc_interp
28 : USE cube_utils, ONLY: cube_info_type
29 : USE input_constants, ONLY: do_par_atom,&
30 : do_qmmm_coulomb,&
31 : do_qmmm_gauss,&
32 : do_qmmm_none,&
33 : do_qmmm_pcharge,&
34 : do_qmmm_swave
35 : USE input_section_types, ONLY: section_get_ivals,&
36 : section_vals_get_subs_vals,&
37 : section_vals_type,&
38 : section_vals_val_get
39 : USE kinds, ONLY: dp
40 : USE message_passing, ONLY: mp_para_env_type
41 : USE mm_collocate_potential, ONLY: collocate_gf_rspace_NoPBC
42 : USE particle_list_types, ONLY: particle_list_type
43 : USE particle_types, ONLY: particle_type
44 : USE pw_env_types, ONLY: pw_env_get,&
45 : pw_env_type
46 : USE pw_methods, ONLY: pw_zero
47 : USE pw_pool_types, ONLY: pw_pool_p_type,&
48 : pw_pools_create_pws,&
49 : pw_pools_give_back_pws
50 : USE pw_types, ONLY: pw_r3d_rs_type
51 : USE qmmm_gaussian_types, ONLY: qmmm_gaussian_p_type,&
52 : qmmm_gaussian_type
53 : USE qmmm_se_energy, ONLY: build_se_qmmm_matrix
54 : USE qmmm_tb_methods, ONLY: build_tb_qmmm_matrix,&
55 : build_tb_qmmm_matrix_pc,&
56 : build_tb_qmmm_matrix_zero
57 : USE qmmm_types_low, ONLY: qmmm_env_qm_type,&
58 : qmmm_per_pot_p_type,&
59 : qmmm_per_pot_type,&
60 : qmmm_pot_p_type,&
61 : qmmm_pot_type
62 : USE qmmm_util, ONLY: spherical_cutoff_factor
63 : USE qs_environment_types, ONLY: get_qs_env,&
64 : qs_environment_type
65 : USE qs_ks_qmmm_types, ONLY: qs_ks_qmmm_env_type
66 : USE qs_subsys_types, ONLY: qs_subsys_get,&
67 : qs_subsys_type
68 : #include "./base/base_uses.f90"
69 :
70 : IMPLICIT NONE
71 : PRIVATE
72 :
73 : LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .FALSE.
74 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qmmm_gpw_energy'
75 :
76 : PUBLIC :: qmmm_el_coupling
77 : PUBLIC :: qmmm_elec_with_gaussian, &
78 : qmmm_elec_with_gaussian_LR, qmmm_elec_with_gaussian_LG
79 : !***
80 : CONTAINS
81 :
82 : ! **************************************************************************************************
83 : !> \brief Main Driver to compute the QM/MM Electrostatic Coupling
84 : !> \param qs_env ...
85 : !> \param qmmm_env ...
86 : !> \param mm_particles ...
87 : !> \param mm_cell ...
88 : !> \par History
89 : !> 05.2004 created [tlaino]
90 : !> \author Teodoro Laino
91 : ! **************************************************************************************************
92 3802 : SUBROUTINE qmmm_el_coupling(qs_env, qmmm_env, mm_particles, mm_cell)
93 : TYPE(qs_environment_type), POINTER :: qs_env
94 : TYPE(qmmm_env_qm_type), POINTER :: qmmm_env
95 : TYPE(particle_type), DIMENSION(:), POINTER :: mm_particles
96 : TYPE(cell_type), POINTER :: mm_cell
97 :
98 : CHARACTER(len=*), PARAMETER :: routineN = 'qmmm_el_coupling'
99 :
100 : INTEGER :: handle, iw, iw2
101 : LOGICAL :: mpi_io
102 : TYPE(cp_logger_type), POINTER :: logger
103 : TYPE(dft_control_type), POINTER :: dft_control
104 : TYPE(mp_para_env_type), POINTER :: para_env
105 : TYPE(particle_list_type), POINTER :: particles
106 : TYPE(pw_env_type), POINTER :: pw_env
107 3802 : TYPE(pw_pool_p_type), DIMENSION(:), POINTER :: pw_pools
108 : TYPE(qs_ks_qmmm_env_type), POINTER :: ks_qmmm_env_loc
109 : TYPE(qs_subsys_type), POINTER :: subsys
110 : TYPE(section_vals_type), POINTER :: input_section, interp_section, &
111 : print_section
112 :
113 3802 : CALL timeset(routineN, handle)
114 3802 : logger => cp_get_default_logger()
115 3802 : NULLIFY (ks_qmmm_env_loc, pw_pools, pw_env, input_section, dft_control)
116 : CALL get_qs_env(qs_env=qs_env, &
117 : pw_env=pw_env, &
118 : para_env=para_env, &
119 : input=input_section, &
120 : ks_qmmm_env=ks_qmmm_env_loc, &
121 : subsys=subsys, &
122 3802 : dft_control=dft_control)
123 3802 : CALL qs_subsys_get(subsys, particles=particles)
124 :
125 3802 : CALL pw_env_get(pw_env=pw_env, pw_pools=pw_pools)
126 3802 : print_section => section_vals_get_subs_vals(input_section, "QMMM%PRINT")
127 : iw = cp_print_key_unit_nr(logger, print_section, "PROGRAM_RUN_INFO", &
128 3802 : extension=".qmmmLog")
129 3802 : IF (iw > 0) &
130 1023 : WRITE (iw, '(T2,"QMMM|",1X,A)') "Information on the QM/MM Electrostatic Potential:"
131 : !
132 : ! Initializing vectors:
133 : ! Zeroing v_qmmm_rspace
134 3802 : CALL pw_zero(ks_qmmm_env_loc%v_qmmm_rspace)
135 3802 : IF (dft_control%qs_control%semi_empirical) THEN
136 : ! SEMIEMPIRICAL
137 2892 : SELECT CASE (qmmm_env%qmmm_coupl_type)
138 : CASE (do_qmmm_coulomb, do_qmmm_none)
139 1446 : CALL build_se_qmmm_matrix(qs_env, qmmm_env, mm_particles, mm_cell, para_env)
140 1446 : IF (qmmm_env%qmmm_coupl_type == do_qmmm_none) THEN
141 510 : IF (iw > 0) WRITE (iw, '(T2,"QMMM|",1X,A)') &
142 176 : "No QM/MM Electrostatic coupling. Just Mechanical Coupling!"
143 : END IF
144 : CASE (do_qmmm_pcharge)
145 0 : CPABORT("Point charge QM/MM electrostatic coupling not yet implemented for SE.")
146 : CASE (do_qmmm_gauss, do_qmmm_swave)
147 0 : CPABORT("GAUSS or SWAVE QM/MM electrostatic coupling not yet implemented for SE.")
148 : CASE DEFAULT
149 0 : IF (iw > 0) WRITE (iw, '(T2,"QMMM|",1X,A)') "Unknown Coupling..."
150 1446 : CPABORT("")
151 : END SELECT
152 2356 : ELSEIF (dft_control%qs_control%dftb .OR. dft_control%qs_control%xtb) THEN
153 : ! DFTB
154 1580 : SELECT CASE (qmmm_env%qmmm_coupl_type)
155 : CASE (do_qmmm_none)
156 8 : IF (iw > 0) WRITE (iw, '(T2,"QMMM|",1X,A)') &
157 4 : "No QM/MM Electrostatic coupling. Just Mechanical Coupling!"
158 8 : CALL build_tb_qmmm_matrix_zero(qs_env, para_env)
159 : CASE (do_qmmm_coulomb)
160 448 : CALL build_tb_qmmm_matrix(qs_env, qmmm_env, mm_particles, mm_cell, para_env)
161 : CASE (do_qmmm_pcharge)
162 1116 : CALL build_tb_qmmm_matrix_pc(qs_env, qmmm_env, mm_particles, mm_cell, para_env)
163 : CASE (do_qmmm_gauss, do_qmmm_swave)
164 0 : CPABORT("GAUSS or SWAVE QM/MM electrostatic coupling not implemented for DFTB.")
165 : CASE DEFAULT
166 0 : IF (iw > 0) WRITE (iw, '(T2,"QMMM|",1X,A)') "Unknown Coupling..."
167 1572 : CPABORT("")
168 : END SELECT
169 : ELSE
170 : ! QS
171 784 : SELECT CASE (qmmm_env%qmmm_coupl_type)
172 : CASE (do_qmmm_coulomb)
173 0 : CPABORT("Coulomb QM/MM electrostatic coupling not implemented for GPW/GAPW.")
174 : CASE (do_qmmm_pcharge)
175 0 : CPABORT("Point Charge QM/MM electrostatic coupling not implemented for GPW/GAPW.")
176 : CASE (do_qmmm_gauss, do_qmmm_swave)
177 744 : IF (iw > 0) &
178 : WRITE (iw, '(T2,"QMMM|",1X,A)') &
179 372 : "QM/MM Coupling computed collocating the Gaussian Potential Functions."
180 : interp_section => section_vals_get_subs_vals(input_section, &
181 744 : "QMMM%INTERPOLATOR")
182 : CALL qmmm_elec_with_gaussian(qmmm_env=qmmm_env, &
183 : v_qmmm=ks_qmmm_env_loc%v_qmmm_rspace, &
184 : mm_particles=mm_particles, &
185 : aug_pools=qmmm_env%aug_pools, &
186 : para_env=para_env, &
187 : eps_mm_rspace=qmmm_env%eps_mm_rspace, &
188 : cube_info=ks_qmmm_env_loc%cube_info, &
189 : pw_pools=pw_pools, &
190 : auxbas_grid=qmmm_env%gridlevel_info%auxbas_grid, &
191 : coarser_grid=qmmm_env%gridlevel_info%coarser_grid, &
192 : interp_section=interp_section, &
193 744 : mm_cell=mm_cell)
194 : CASE (do_qmmm_none)
195 40 : IF (iw > 0) WRITE (iw, '(T2,"QMMM|",1X,A)') &
196 20 : "No QM/MM Electrostatic coupling. Just Mechanical Coupling!"
197 : CASE DEFAULT
198 0 : IF (iw > 0) WRITE (iw, '(T2,"QMMM|",1X,A)') "Unknown Coupling..."
199 784 : CPABORT("")
200 : END SELECT
201 : ! Dump info on the electrostatic potential if requested
202 784 : IF (BTEST(cp_print_key_should_output(logger%iter_info, print_section, &
203 : "POTENTIAL"), cp_p_file)) THEN
204 24 : mpi_io = .TRUE.
205 : iw2 = cp_print_key_unit_nr(logger, print_section, "POTENTIAL", &
206 24 : extension=".qmmmLog", mpi_io=mpi_io)
207 : CALL cp_pw_to_cube(ks_qmmm_env_loc%v_qmmm_rspace, iw2, &
208 : particles=particles, &
209 : stride=section_get_ivals(print_section, "POTENTIAL%STRIDE"), &
210 : title="QM/MM: MM ELECTROSTATIC POTENTIAL ", &
211 24 : mpi_io=mpi_io)
212 : CALL cp_print_key_finished_output(iw2, logger, print_section, &
213 24 : "POTENTIAL", mpi_io=mpi_io)
214 : END IF
215 : END IF
216 : CALL cp_print_key_finished_output(iw, logger, print_section, &
217 3802 : "PROGRAM_RUN_INFO")
218 3802 : CALL timestop(handle)
219 3802 : END SUBROUTINE qmmm_el_coupling
220 :
221 : ! **************************************************************************************************
222 : !> \brief Compute the QM/MM electrostatic Interaction collocating the gaussian
223 : !> Electrostatic Potential
224 : !> \param qmmm_env ...
225 : !> \param v_qmmm ...
226 : !> \param mm_particles ...
227 : !> \param aug_pools ...
228 : !> \param cube_info ...
229 : !> \param para_env ...
230 : !> \param eps_mm_rspace ...
231 : !> \param pw_pools ...
232 : !> \param auxbas_grid ...
233 : !> \param coarser_grid ...
234 : !> \param interp_section ...
235 : !> \param mm_cell ...
236 : !> \par History
237 : !> 06.2004 created [tlaino]
238 : !> \author Teodoro Laino
239 : ! **************************************************************************************************
240 744 : SUBROUTINE qmmm_elec_with_gaussian(qmmm_env, v_qmmm, mm_particles, &
241 : aug_pools, cube_info, para_env, eps_mm_rspace, pw_pools, &
242 : auxbas_grid, coarser_grid, interp_section, mm_cell)
243 : TYPE(qmmm_env_qm_type), POINTER :: qmmm_env
244 : TYPE(pw_r3d_rs_type), INTENT(IN) :: v_qmmm
245 : TYPE(particle_type), DIMENSION(:), POINTER :: mm_particles
246 : TYPE(pw_pool_p_type), DIMENSION(:), POINTER :: aug_pools
247 : TYPE(cube_info_type), DIMENSION(:), POINTER :: cube_info
248 : TYPE(mp_para_env_type), POINTER :: para_env
249 : REAL(KIND=dp), INTENT(IN) :: eps_mm_rspace
250 : TYPE(pw_pool_p_type), DIMENSION(:), POINTER :: pw_pools
251 : INTEGER, INTENT(IN) :: auxbas_grid, coarser_grid
252 : TYPE(section_vals_type), POINTER :: interp_section
253 : TYPE(cell_type), POINTER :: mm_cell
254 :
255 : CHARACTER(len=*), PARAMETER :: routineN = 'qmmm_elec_with_gaussian'
256 :
257 : INTEGER :: handle, handle2, igrid, ilevel, &
258 : kind_interp, lb(3), ngrids, ub(3)
259 : LOGICAL :: shells
260 744 : TYPE(pw_r3d_rs_type), ALLOCATABLE, DIMENSION(:) :: grids
261 :
262 744 : CPASSERT(ASSOCIATED(mm_particles))
263 744 : CPASSERT(ASSOCIATED(qmmm_env%mm_atom_chrg))
264 744 : CPASSERT(ASSOCIATED(qmmm_env%mm_atom_index))
265 744 : CPASSERT(ASSOCIATED(aug_pools))
266 744 : CPASSERT(ASSOCIATED(pw_pools))
267 : !Statements
268 744 : CALL timeset(routineN, handle)
269 744 : ngrids = SIZE(pw_pools)
270 744 : CALL pw_pools_create_pws(aug_pools, grids)
271 3748 : DO igrid = 1, ngrids
272 3748 : CALL pw_zero(grids(igrid))
273 : END DO
274 :
275 744 : shells = .FALSE.
276 :
277 : CALL qmmm_elec_with_gaussian_low(grids, mm_particles, &
278 : qmmm_env%mm_atom_chrg, qmmm_env%mm_atom_index, &
279 : cube_info, para_env, eps_mm_rspace, qmmm_env%pgfs, &
280 : auxbas_grid, coarser_grid, qmmm_env%potentials, &
281 : mm_cell=mm_cell, dOmmOqm=qmmm_env%dOmmOqm, periodic=qmmm_env%periodic, &
282 : per_potentials=qmmm_env%per_potentials, par_scheme=qmmm_env%par_scheme, &
283 744 : qmmm_spherical_cutoff=qmmm_env%spherical_cutoff, shells=shells)
284 :
285 744 : IF (qmmm_env%move_mm_charges .OR. qmmm_env%add_mm_charges) THEN
286 : CALL qmmm_elec_with_gaussian_low(grids, qmmm_env%added_charges%added_particles, &
287 : qmmm_env%added_charges%mm_atom_chrg, &
288 : qmmm_env%added_charges%mm_atom_index, &
289 : cube_info, para_env, eps_mm_rspace, qmmm_env%added_charges%pgfs, auxbas_grid, &
290 : coarser_grid, qmmm_env%added_charges%potentials, &
291 : mm_cell=mm_cell, dOmmOqm=qmmm_env%dOmmOqm, periodic=qmmm_env%periodic, &
292 : per_potentials=qmmm_env%added_charges%per_potentials, par_scheme=qmmm_env%par_scheme, &
293 32 : qmmm_spherical_cutoff=qmmm_env%spherical_cutoff, shells=shells)
294 : END IF
295 744 : IF (qmmm_env%added_shells%num_mm_atoms .GT. 0) THEN
296 2 : shells = .TRUE.
297 : CALL qmmm_elec_with_gaussian_low(grids, qmmm_env%added_shells%added_particles, &
298 : qmmm_env%added_shells%mm_core_chrg, &
299 : qmmm_env%added_shells%mm_core_index, &
300 : cube_info, para_env, eps_mm_rspace, qmmm_env%added_shells%pgfs, auxbas_grid, &
301 : coarser_grid, qmmm_env%added_shells%potentials, &
302 : mm_cell=mm_cell, dOmmOqm=qmmm_env%dOmmOqm, periodic=qmmm_env%periodic, &
303 : per_potentials=qmmm_env%added_shells%per_potentials, &
304 : par_scheme=qmmm_env%par_scheme, qmmm_spherical_cutoff=qmmm_env%spherical_cutoff, &
305 2 : shells=shells)
306 : END IF
307 : ! Sumup all contributions according the parallelization scheme
308 744 : IF (qmmm_env%par_scheme == do_par_atom) THEN
309 3708 : DO ilevel = 1, SIZE(grids)
310 3708 : CALL para_env%sum(grids(ilevel)%array)
311 : END DO
312 : END IF
313 : ! RealSpace Interpolation
314 744 : CALL section_vals_val_get(interp_section, "kind", i_val=kind_interp)
315 744 : SELECT CASE (kind_interp)
316 : CASE (spline3_nopbc_interp, spline3_pbc_interp)
317 : ! Spline Iterpolator
318 744 : CALL para_env%sync()
319 744 : CALL timeset(TRIM(routineN)//":spline3Int", handle2)
320 3004 : DO Ilevel = coarser_grid, auxbas_grid + 1, -1
321 : CALL pw_prolongate_s3(grids(Ilevel), &
322 : grids(Ilevel - 1), &
323 : aug_pools(Ilevel)%pool, &
324 3004 : param_section=interp_section)
325 : END DO
326 744 : CALL timestop(handle2)
327 : CASE DEFAULT
328 1488 : CPABORT("")
329 : END SELECT
330 2976 : lb = v_qmmm%pw_grid%bounds_local(1, :)
331 2976 : ub = v_qmmm%pw_grid%bounds_local(2, :)
332 :
333 : v_qmmm%array = grids(auxbas_grid)%array(lb(1):ub(1), &
334 : lb(2):ub(2), &
335 33223912 : lb(3):ub(3))
336 :
337 744 : CALL pw_pools_give_back_pws(aug_pools, grids)
338 :
339 744 : CALL timestop(handle)
340 744 : END SUBROUTINE qmmm_elec_with_gaussian
341 :
342 : ! **************************************************************************************************
343 : !> \brief Compute the QM/MM electrostatic Interaction collocating the gaussian
344 : !> Electrostatic Potential - Low Level
345 : !> \param tmp_grid ...
346 : !> \param mm_particles ...
347 : !> \param mm_charges ...
348 : !> \param mm_atom_index ...
349 : !> \param cube_info ...
350 : !> \param para_env ...
351 : !> \param eps_mm_rspace ...
352 : !> \param pgfs ...
353 : !> \param auxbas_grid ...
354 : !> \param coarser_grid ...
355 : !> \param potentials ...
356 : !> \param mm_cell ...
357 : !> \param dOmmOqm ...
358 : !> \param periodic ...
359 : !> \param per_potentials ...
360 : !> \param par_scheme ...
361 : !> \param qmmm_spherical_cutoff ...
362 : !> \param shells ...
363 : !> \par History
364 : !> 06.2004 created [tlaino]
365 : !> \author Teodoro Laino
366 : ! **************************************************************************************************
367 778 : SUBROUTINE qmmm_elec_with_gaussian_low(tmp_grid, mm_particles, mm_charges, &
368 : mm_atom_index, cube_info, para_env, &
369 : eps_mm_rspace, pgfs, auxbas_grid, coarser_grid, &
370 : potentials, mm_cell, dOmmOqm, periodic, per_potentials, par_scheme, &
371 : qmmm_spherical_cutoff, shells)
372 : TYPE(pw_r3d_rs_type), DIMENSION(:), INTENT(IN) :: tmp_grid
373 : TYPE(particle_type), DIMENSION(:), POINTER :: mm_particles
374 : REAL(KIND=dp), DIMENSION(:), POINTER :: mm_charges
375 : INTEGER, DIMENSION(:), POINTER :: mm_atom_index
376 : TYPE(cube_info_type), DIMENSION(:), POINTER :: cube_info
377 : TYPE(mp_para_env_type), POINTER :: para_env
378 : REAL(KIND=dp), INTENT(IN) :: eps_mm_rspace
379 : TYPE(qmmm_gaussian_p_type), DIMENSION(:), POINTER :: pgfs
380 : INTEGER, INTENT(IN) :: auxbas_grid, coarser_grid
381 : TYPE(qmmm_pot_p_type), DIMENSION(:), POINTER :: potentials
382 : TYPE(cell_type), POINTER :: mm_cell
383 : REAL(KIND=dp), DIMENSION(3), INTENT(IN) :: dOmmOqm
384 : LOGICAL, INTENT(IN) :: periodic
385 : TYPE(qmmm_per_pot_p_type), DIMENSION(:), POINTER :: per_potentials
386 : INTEGER, INTENT(IN) :: par_scheme
387 : REAL(KIND=dp), INTENT(IN) :: qmmm_spherical_cutoff(2)
388 : LOGICAL, INTENT(IN) :: shells
389 :
390 : CHARACTER(len=*), PARAMETER :: routineN = 'qmmm_elec_with_gaussian_low', &
391 : routineNb = 'qmmm_elec_gaussian_low'
392 :
393 : INTEGER :: handle, handle2, IGauss, ilevel, Imm, &
394 : IndMM, IRadTyp, LIndMM, myind, &
395 : n_rep_real(3)
396 : INTEGER, DIMENSION(2, 3) :: bo2
397 : REAL(KIND=dp) :: alpha, height, sph_chrg_factor, W
398 : REAL(KIND=dp), DIMENSION(3) :: ra
399 778 : REAL(KIND=dp), DIMENSION(:), POINTER :: xdat, ydat, zdat
400 : TYPE(qmmm_gaussian_type), POINTER :: pgf
401 : TYPE(qmmm_per_pot_type), POINTER :: per_pot
402 : TYPE(qmmm_pot_type), POINTER :: pot
403 :
404 778 : NULLIFY (pgf, pot, per_pot, xdat, ydat, zdat)
405 778 : CALL timeset(routineN, handle)
406 778 : CALL timeset(routineNb//"_G", handle2)
407 7780 : bo2 = tmp_grid(auxbas_grid)%pw_grid%bounds
408 2334 : ALLOCATE (xdat(bo2(1, 1):bo2(2, 1)))
409 2334 : ALLOCATE (ydat(bo2(1, 2):bo2(2, 2)))
410 2334 : ALLOCATE (zdat(bo2(1, 3):bo2(2, 3)))
411 : IF (par_scheme == do_par_atom) myind = 0
412 2176 : Radius: DO IRadTyp = 1, SIZE(pgfs)
413 1398 : pgf => pgfs(IRadTyp)%pgf
414 1398 : pot => potentials(IRadTyp)%pot
415 1398 : n_rep_real = 0
416 1398 : IF (periodic) THEN
417 102 : per_pot => per_potentials(IRadTyp)%pot
418 408 : n_rep_real = per_pot%n_rep_real
419 : END IF
420 12088 : Gaussian: DO IGauss = 1, pgf%Number_of_Gaussians
421 9912 : alpha = 1.0_dp/pgf%Gk(IGauss)
422 9912 : alpha = alpha*alpha
423 9912 : height = pgf%Ak(IGauss)
424 9912 : ilevel = pgf%grid_level(IGauss)
425 60616 : Atoms: DO Imm = 1, SIZE(pot%mm_atom_index)
426 49306 : IF (par_scheme == do_par_atom) THEN
427 48690 : myind = myind + 1
428 48690 : IF (MOD(myind, para_env%num_pe) /= para_env%mepos) CYCLE Atoms
429 : END IF
430 25009 : LIndMM = pot%mm_atom_index(Imm)
431 25009 : IndMM = mm_atom_index(LIndMM)
432 25009 : IF (shells) THEN
433 1344 : ra(:) = pbc(mm_particles(LIndMM)%r - dOmmOqm, mm_cell) + dOmmOqm
434 : ELSE
435 198728 : ra(:) = pbc(mm_particles(IndMM)%r - dOmmOqm, mm_cell) + dOmmOqm
436 : END IF
437 25009 : W = mm_charges(LIndMM)*height
438 : ! Possible Spherical Cutoff
439 25009 : IF (qmmm_spherical_cutoff(1) > 0.0_dp) THEN
440 0 : CALL spherical_cutoff_factor(qmmm_spherical_cutoff, ra, sph_chrg_factor)
441 0 : W = W*sph_chrg_factor
442 : END IF
443 25009 : IF (ABS(W) <= EPSILON(0.0_dp)) CYCLE Atoms
444 : CALL collocate_gf_rspace_NoPBC(zetp=alpha, &
445 : rp=ra, &
446 : scale=-1.0_dp, &
447 : W=W, &
448 : pwgrid=tmp_grid(ilevel), &
449 : cube_info=cube_info(ilevel), &
450 : eps_mm_rspace=eps_mm_rspace, &
451 : xdat=xdat, &
452 : ydat=ydat, &
453 : zdat=zdat, &
454 : bo2=bo2, &
455 : n_rep_real=n_rep_real, &
456 59218 : mm_cell=mm_cell)
457 : END DO Atoms
458 : END DO Gaussian
459 : END DO Radius
460 778 : IF (ASSOCIATED(xdat)) THEN
461 778 : DEALLOCATE (xdat)
462 : END IF
463 778 : IF (ASSOCIATED(ydat)) THEN
464 778 : DEALLOCATE (ydat)
465 : END IF
466 778 : IF (ASSOCIATED(zdat)) THEN
467 778 : DEALLOCATE (zdat)
468 : END IF
469 778 : CALL timestop(handle2)
470 778 : CALL timeset(routineNb//"_R", handle2)
471 778 : IF (periodic) THEN
472 : ! Long Range Part of the QM/MM Potential with Gaussians With Periodic Boundary Conditions
473 : CALL qmmm_elec_with_gaussian_LG(pgfs=pgfs, &
474 : cgrid=tmp_grid(coarser_grid), &
475 : mm_charges=mm_charges, &
476 : mm_atom_index=mm_atom_index, &
477 : mm_particles=mm_particles, &
478 : para_env=para_env, &
479 : per_potentials=per_potentials, &
480 : mm_cell=mm_cell, &
481 : dOmmOqm=dOmmOqm, &
482 : par_scheme=par_scheme, &
483 : qmmm_spherical_cutoff=qmmm_spherical_cutoff, &
484 64 : shells=shells)
485 : ELSE
486 : ! Long Range Part of the QM/MM Potential with Gaussians
487 : CALL qmmm_elec_with_gaussian_LR(pgfs=pgfs, &
488 : grid=tmp_grid(coarser_grid), &
489 : mm_charges=mm_charges, &
490 : mm_atom_index=mm_atom_index, &
491 : mm_particles=mm_particles, &
492 : para_env=para_env, &
493 : potentials=potentials, &
494 : mm_cell=mm_cell, &
495 : dOmmOqm=dOmmOqm, &
496 : par_scheme=par_scheme, &
497 : qmmm_spherical_cutoff=qmmm_spherical_cutoff, &
498 714 : shells=shells)
499 : END IF
500 778 : CALL timestop(handle2)
501 778 : CALL timestop(handle)
502 :
503 1556 : END SUBROUTINE qmmm_elec_with_gaussian_low
504 :
505 : ! **************************************************************************************************
506 : !> \brief Compute the QM/MM electrostatic Interaction collocating
507 : !> (1/R - Sum_NG Gaussians) on the coarser grid level in G-SPACE
508 : !> Long Range QM/MM Electrostatic Potential with Gaussian - Low Level
509 : !> PERIODIC BOUNDARY CONDITION VERSION
510 : !> \param pgfs ...
511 : !> \param cgrid ...
512 : !> \param mm_charges ...
513 : !> \param mm_atom_index ...
514 : !> \param mm_particles ...
515 : !> \param para_env ...
516 : !> \param per_potentials ...
517 : !> \param mm_cell ...
518 : !> \param dOmmOqm ...
519 : !> \param par_scheme ...
520 : !> \param qmmm_spherical_cutoff ...
521 : !> \param shells ...
522 : !> \par History
523 : !> 07.2004 created [tlaino]
524 : !> \author Teodoro Laino
525 : !> \note
526 : !> This version includes the explicit code of Eval_Interp_Spl3_pbc
527 : !> in order to achieve better performance
528 : ! **************************************************************************************************
529 64 : SUBROUTINE qmmm_elec_with_gaussian_LG(pgfs, cgrid, mm_charges, mm_atom_index, &
530 : mm_particles, para_env, per_potentials, &
531 : mm_cell, dOmmOqm, par_scheme, qmmm_spherical_cutoff, shells)
532 : TYPE(qmmm_gaussian_p_type), DIMENSION(:), POINTER :: pgfs
533 : TYPE(pw_r3d_rs_type), INTENT(IN) :: cgrid
534 : REAL(KIND=dp), DIMENSION(:), POINTER :: mm_charges
535 : INTEGER, DIMENSION(:), POINTER :: mm_atom_index
536 : TYPE(particle_type), DIMENSION(:), POINTER :: mm_particles
537 : TYPE(mp_para_env_type), POINTER :: para_env
538 : TYPE(qmmm_per_pot_p_type), DIMENSION(:), POINTER :: per_potentials
539 : TYPE(cell_type), POINTER :: mm_cell
540 : REAL(KIND=dp), DIMENSION(3), INTENT(IN) :: dOmmOqm
541 : INTEGER, INTENT(IN) :: par_scheme
542 : REAL(KIND=dp), DIMENSION(2), INTENT(IN) :: qmmm_spherical_cutoff
543 : LOGICAL :: shells
544 :
545 : CHARACTER(len=*), PARAMETER :: routineN = 'qmmm_elec_with_gaussian_LG'
546 :
547 : INTEGER :: handle, i, ii1, ii2, ii3, ii4, ij1, ij2, &
548 : ij3, ij4, ik1, ik2, ik3, ik4, Imm, &
549 : IndMM, IRadTyp, ivec(3), j, k, LIndMM, &
550 : my_j, my_k, myind, npts(3)
551 : INTEGER, DIMENSION(2, 3) :: bo, gbo
552 : REAL(KIND=dp) :: a1, a2, a3, abc_X(4, 4), abc_X_Y(4), b1, b2, b3, c1, c2, c3, d1, d2, d3, &
553 : dr1, dr1c, dr2, dr2c, dr3, dr3c, e1, e2, e3, f1, f2, f3, g1, g2, g3, h1, h2, h3, p1, p2, &
554 : p3, q1, q2, q3, qt, r1, r2, r3, rt1, rt2, rt3, rv1, rv2, rv3, s1, s2, s3, s4, &
555 : sph_chrg_factor, t1, t2, t3, t4, u1, u2, u3, v1, v2, v3, v4, val, xd1, xd2, xd3, xs1, &
556 : xs2, xs3
557 : REAL(KIND=dp), DIMENSION(3) :: ra, vec
558 64 : REAL(KIND=dp), DIMENSION(:, :, :), POINTER :: grid, grid2
559 : TYPE(pw_r3d_rs_type), POINTER :: pw
560 : TYPE(qmmm_per_pot_type), POINTER :: per_pot
561 :
562 64 : CALL timeset(routineN, handle)
563 64 : NULLIFY (grid, pw)
564 64 : dr1c = cgrid%pw_grid%dr(1)
565 64 : dr2c = cgrid%pw_grid%dr(2)
566 64 : dr3c = cgrid%pw_grid%dr(3)
567 640 : gbo = cgrid%pw_grid%bounds
568 640 : bo = cgrid%pw_grid%bounds_local
569 64 : grid2 => cgrid%array
570 64 : IF (par_scheme == do_par_atom) myind = 0
571 166 : Radius: DO IRadTyp = 1, SIZE(pgfs)
572 102 : per_pot => per_potentials(IRadTyp)%pot
573 102 : pw => per_pot%TabLR
574 408 : npts = pw%pw_grid%npts
575 102 : dr1 = pw%pw_grid%dr(1)
576 102 : dr2 = pw%pw_grid%dr(2)
577 102 : dr3 = pw%pw_grid%dr(3)
578 102 : grid => pw%array(:, :, :)
579 : !$OMP PARALLEL DO DEFAULT(NONE) &
580 : !$OMP SHARED(bo, gbo, grid, grid2, pw, npts, per_pot, mm_atom_index) &
581 : !$OMP SHARED(dr1, dr2, dr3, dr1c, dr2c, dr3c, par_scheme, mm_charges, mm_particles) &
582 : !$OMP SHARED(mm_cell, dOmmOqm, shells, para_env, IRadTyp, qmmm_spherical_cutoff) &
583 : !$OMP PRIVATE(Imm, LIndMM, IndMM, qt, sph_chrg_factor, ra, myind) &
584 : !$OMP PRIVATE(rt1, rt2, rt3, k, vec, ivec, xd1, xd2, xd3, ik1, ik2, ik3, ik4) &
585 : !$OMP PRIVATE(ij1, ij2, ij3, ij4, ii1, ii2, ii3, ii4, my_k, my_j, xs1, xs2, xs3) &
586 : !$OMP PRIVATE(p1, p2, p3, q1, q2, q3, r1, r2, r3, v1, v2, v3, v4, e1, e2, e3) &
587 : !$OMP PRIVATE(f1, f2, f3, g1, g2, g3, h1, h2, h3, s1, s2, s3, s4, a1, a2, a3) &
588 : !$OMP PRIVATE(b1, b2, b3, c1, c2, c3, d1, d2, d3, t1, t2, t3, t4, u1, u2, u3, val) &
589 166 : !$OMP PRIVATE(rv1, rv2, rv3, abc_X, abc_X_Y)
590 : Atoms: DO Imm = 1, SIZE(per_pot%mm_atom_index)
591 : IF (par_scheme == do_par_atom) THEN
592 : myind = Imm + (IRadTyp - 1)*SIZE(per_pot%mm_atom_index)
593 : IF (MOD(myind, para_env%num_pe) /= para_env%mepos) CYCLE
594 : END IF
595 : LIndMM = per_pot%mm_atom_index(Imm)
596 : IndMM = mm_atom_index(LIndMM)
597 : qt = mm_charges(LIndMM)
598 : IF (shells) THEN
599 : ra(:) = pbc(mm_particles(LIndMM)%r - dOmmOqm, mm_cell) + dOmmOqm
600 : ELSE
601 : ra(:) = pbc(mm_particles(IndMM)%r - dOmmOqm, mm_cell) + dOmmOqm
602 : END IF
603 : ! Possible Spherical Cutoff
604 : IF (qmmm_spherical_cutoff(1) > 0.0_dp) THEN
605 : CALL spherical_cutoff_factor(qmmm_spherical_cutoff, ra, sph_chrg_factor)
606 : qt = qt*sph_chrg_factor
607 : END IF
608 : IF (ABS(qt) <= EPSILON(0.0_dp)) CYCLE Atoms
609 : rt1 = ra(1)
610 : rt2 = ra(2)
611 : rt3 = ra(3)
612 : LoopOnGrid: DO k = bo(1, 3), bo(2, 3)
613 : my_k = k - gbo(1, 3)
614 : xs3 = REAL(my_k, dp)*dr3c
615 : my_j = bo(1, 2) - gbo(1, 2)
616 : xs2 = REAL(my_j, dp)*dr2c
617 : rv3 = rt3 - xs3
618 : vec(3) = rv3
619 : ivec(3) = FLOOR(vec(3)/pw%pw_grid%dr(3))
620 : xd3 = (vec(3)/dr3) - REAL(ivec(3), kind=dp)
621 : ik1 = MODULO(ivec(3) - 1, npts(3)) + 1
622 : ik2 = MODULO(ivec(3), npts(3)) + 1
623 : ik3 = MODULO(ivec(3) + 1, npts(3)) + 1
624 : ik4 = MODULO(ivec(3) + 2, npts(3)) + 1
625 : p1 = 3.0_dp + xd3
626 : p2 = p1*p1
627 : p3 = p2*p1
628 : q1 = 2.0_dp + xd3
629 : q2 = q1*q1
630 : q3 = q2*q1
631 : r1 = 1.0_dp + xd3
632 : r2 = r1*r1
633 : r3 = r2*r1
634 : u1 = xd3
635 : u2 = u1*u1
636 : u3 = u2*u1
637 : v1 = 1.0_dp/6.0_dp*(64.0_dp - 48.0_dp*p1 + 12.0_dp*p2 - p3)
638 : v2 = -22.0_dp/3.0_dp + 10.0_dp*q1 - 4.0_dp*q2 + 0.5_dp*q3
639 : v3 = 2.0_dp/3.0_dp - 2.0_dp*r1 + 2.0_dp*r2 - 0.5_dp*r3
640 : v4 = 1.0_dp/6.0_dp*u3
641 : DO j = bo(1, 2), bo(2, 2)
642 : xs1 = (bo(1, 1) - gbo(1, 1))*dr1c
643 : rv2 = rt2 - xs2
644 : vec(2) = rv2
645 : ivec(2) = FLOOR(vec(2)/pw%pw_grid%dr(2))
646 : xd2 = (vec(2)/dr2) - REAL(ivec(2), kind=dp)
647 : ij1 = MODULO(ivec(2) - 1, npts(2)) + 1
648 : ij2 = MODULO(ivec(2), npts(2)) + 1
649 : ij3 = MODULO(ivec(2) + 1, npts(2)) + 1
650 : ij4 = MODULO(ivec(2) + 2, npts(2)) + 1
651 : e1 = 3.0_dp + xd2
652 : e2 = e1*e1
653 : e3 = e2*e1
654 : f1 = 2.0_dp + xd2
655 : f2 = f1*f1
656 : f3 = f2*f1
657 : g1 = 1.0_dp + xd2
658 : g2 = g1*g1
659 : g3 = g2*g1
660 : h1 = xd2
661 : h2 = h1*h1
662 : h3 = h2*h1
663 : s1 = 1.0_dp/6.0_dp*(64.0_dp - 48.0_dp*e1 + 12.0_dp*e2 - e3)
664 : s2 = -22.0_dp/3.0_dp + 10.0_dp*f1 - 4.0_dp*f2 + 0.5_dp*f3
665 : s3 = 2.0_dp/3.0_dp - 2.0_dp*g1 + 2.0_dp*g2 - 0.5_dp*g3
666 : s4 = 1.0_dp/6.0_dp*h3
667 : DO i = bo(1, 1), bo(2, 1)
668 : rv1 = rt1 - xs1
669 : vec(1) = rv1
670 : ivec(1) = FLOOR(vec(1)/pw%pw_grid%dr(1))
671 : xd1 = (vec(1)/dr1) - REAL(ivec(1), kind=dp)
672 : ii1 = MODULO(ivec(1) - 1, npts(1)) + 1
673 : ii2 = MODULO(ivec(1), npts(1)) + 1
674 : ii3 = MODULO(ivec(1) + 1, npts(1)) + 1
675 : ii4 = MODULO(ivec(1) + 2, npts(1)) + 1
676 : !
677 : ! Spline Interpolation
678 : !
679 :
680 : a1 = 3.0_dp + xd1
681 : a2 = a1*a1
682 : a3 = a2*a1
683 : b1 = 2.0_dp + xd1
684 : b2 = b1*b1
685 : b3 = b2*b1
686 : c1 = 1.0_dp + xd1
687 : c2 = c1*c1
688 : c3 = c2*c1
689 : d1 = xd1
690 : d2 = d1*d1
691 : d3 = d2*d1
692 : t1 = 1.0_dp/6.0_dp*(64.0_dp - 48.0_dp*a1 + 12.0_dp*a2 - a3)
693 : t2 = -22.0_dp/3.0_dp + 10.0_dp*b1 - 4.0_dp*b2 + 0.5_dp*b3
694 : t3 = 2.0_dp/3.0_dp - 2.0_dp*c1 + 2.0_dp*c2 - 0.5_dp*c3
695 : t4 = 1.0_dp/6.0_dp*d3
696 :
697 : abc_X(1, 1) = grid(ii1, ij1, ik1)*v1 + grid(ii1, ij1, ik2)*v2 + grid(ii1, ij1, ik3)*v3 + grid(ii1, ij1, ik4)*v4
698 : abc_X(1, 2) = grid(ii1, ij2, ik1)*v1 + grid(ii1, ij2, ik2)*v2 + grid(ii1, ij2, ik3)*v3 + grid(ii1, ij2, ik4)*v4
699 : abc_X(1, 3) = grid(ii1, ij3, ik1)*v1 + grid(ii1, ij3, ik2)*v2 + grid(ii1, ij3, ik3)*v3 + grid(ii1, ij3, ik4)*v4
700 : abc_X(1, 4) = grid(ii1, ij4, ik1)*v1 + grid(ii1, ij4, ik2)*v2 + grid(ii1, ij4, ik3)*v3 + grid(ii1, ij4, ik4)*v4
701 : abc_X(2, 1) = grid(ii2, ij1, ik1)*v1 + grid(ii2, ij1, ik2)*v2 + grid(ii2, ij1, ik3)*v3 + grid(ii2, ij1, ik4)*v4
702 : abc_X(2, 2) = grid(ii2, ij2, ik1)*v1 + grid(ii2, ij2, ik2)*v2 + grid(ii2, ij2, ik3)*v3 + grid(ii2, ij2, ik4)*v4
703 : abc_X(2, 3) = grid(ii2, ij3, ik1)*v1 + grid(ii2, ij3, ik2)*v2 + grid(ii2, ij3, ik3)*v3 + grid(ii2, ij3, ik4)*v4
704 : abc_X(2, 4) = grid(ii2, ij4, ik1)*v1 + grid(ii2, ij4, ik2)*v2 + grid(ii2, ij4, ik3)*v3 + grid(ii2, ij4, ik4)*v4
705 : abc_X(3, 1) = grid(ii3, ij1, ik1)*v1 + grid(ii3, ij1, ik2)*v2 + grid(ii3, ij1, ik3)*v3 + grid(ii3, ij1, ik4)*v4
706 : abc_X(3, 2) = grid(ii3, ij2, ik1)*v1 + grid(ii3, ij2, ik2)*v2 + grid(ii3, ij2, ik3)*v3 + grid(ii3, ij2, ik4)*v4
707 : abc_X(3, 3) = grid(ii3, ij3, ik1)*v1 + grid(ii3, ij3, ik2)*v2 + grid(ii3, ij3, ik3)*v3 + grid(ii3, ij3, ik4)*v4
708 : abc_X(3, 4) = grid(ii3, ij4, ik1)*v1 + grid(ii3, ij4, ik2)*v2 + grid(ii3, ij4, ik3)*v3 + grid(ii3, ij4, ik4)*v4
709 : abc_X(4, 1) = grid(ii4, ij1, ik1)*v1 + grid(ii4, ij1, ik2)*v2 + grid(ii4, ij1, ik3)*v3 + grid(ii4, ij1, ik4)*v4
710 : abc_X(4, 2) = grid(ii4, ij2, ik1)*v1 + grid(ii4, ij2, ik2)*v2 + grid(ii4, ij2, ik3)*v3 + grid(ii4, ij2, ik4)*v4
711 : abc_X(4, 3) = grid(ii4, ij3, ik1)*v1 + grid(ii4, ij3, ik2)*v2 + grid(ii4, ij3, ik3)*v3 + grid(ii4, ij3, ik4)*v4
712 : abc_X(4, 4) = grid(ii4, ij4, ik1)*v1 + grid(ii4, ij4, ik2)*v2 + grid(ii4, ij4, ik3)*v3 + grid(ii4, ij4, ik4)*v4
713 :
714 : abc_X_Y(1) = abc_X(1, 1)*t1 + abc_X(2, 1)*t2 + abc_X(3, 1)*t3 + abc_X(4, 1)*t4
715 : abc_X_Y(2) = abc_X(1, 2)*t1 + abc_X(2, 2)*t2 + abc_X(3, 2)*t3 + abc_X(4, 2)*t4
716 : abc_X_Y(3) = abc_X(1, 3)*t1 + abc_X(2, 3)*t2 + abc_X(3, 3)*t3 + abc_X(4, 3)*t4
717 : abc_X_Y(4) = abc_X(1, 4)*t1 + abc_X(2, 4)*t2 + abc_X(3, 4)*t3 + abc_X(4, 4)*t4
718 :
719 : val = abc_X_Y(1)*s1 + abc_X_Y(2)*s2 + abc_X_Y(3)*s3 + abc_X_Y(4)*s4
720 : !$OMP ATOMIC
721 : grid2(i, j, k) = grid2(i, j, k) - val*qt
722 : !$OMP END ATOMIC
723 : xs1 = xs1 + dr1c
724 : END DO
725 : xs2 = xs2 + dr2c
726 : END DO
727 : END DO LoopOnGrid
728 : END DO Atoms
729 : !$OMP END PARALLEL DO
730 : END DO Radius
731 64 : CALL timestop(handle)
732 64 : END SUBROUTINE qmmm_elec_with_gaussian_LG
733 :
734 : ! **************************************************************************************************
735 : !> \brief Compute the QM/MM electrostatic Interaction collocating
736 : !> (1/R - Sum_NG Gaussians) on the coarser grid level.
737 : !> Long Range QM/MM Electrostatic Potential with Gaussian - Low Level
738 : !> \param pgfs ...
739 : !> \param grid ...
740 : !> \param mm_charges ...
741 : !> \param mm_atom_index ...
742 : !> \param mm_particles ...
743 : !> \param para_env ...
744 : !> \param potentials ...
745 : !> \param mm_cell ...
746 : !> \param dOmmOqm ...
747 : !> \param par_scheme ...
748 : !> \param qmmm_spherical_cutoff ...
749 : !> \param shells ...
750 : !> \par History
751 : !> 07.2004 created [tlaino]
752 : !> \author Teodoro Laino
753 : ! **************************************************************************************************
754 714 : SUBROUTINE qmmm_elec_with_gaussian_LR(pgfs, grid, mm_charges, mm_atom_index, &
755 : mm_particles, para_env, potentials, &
756 : mm_cell, dOmmOqm, par_scheme, qmmm_spherical_cutoff, shells)
757 : TYPE(qmmm_gaussian_p_type), DIMENSION(:), POINTER :: pgfs
758 : TYPE(pw_r3d_rs_type), INTENT(IN) :: grid
759 : REAL(KIND=dp), DIMENSION(:), POINTER :: mm_charges
760 : INTEGER, DIMENSION(:), POINTER :: mm_atom_index
761 : TYPE(particle_type), DIMENSION(:), POINTER :: mm_particles
762 : TYPE(mp_para_env_type), POINTER :: para_env
763 : TYPE(qmmm_pot_p_type), DIMENSION(:), POINTER :: potentials
764 : TYPE(cell_type), POINTER :: mm_cell
765 : REAL(KIND=dp), DIMENSION(3), INTENT(IN) :: dOmmOqm
766 : INTEGER, INTENT(IN) :: par_scheme
767 : REAL(KIND=dp), DIMENSION(2), INTENT(IN) :: qmmm_spherical_cutoff
768 : LOGICAL :: shells
769 :
770 : CHARACTER(len=*), PARAMETER :: routineN = 'qmmm_elec_with_gaussian_LR'
771 :
772 : INTEGER :: handle, i, Imm, IndMM, IRadTyp, ix, j, &
773 : k, LIndMM, my_j, my_k, myind, n1, n2, &
774 : n3
775 : INTEGER, DIMENSION(2, 3) :: bo, gbo
776 : REAL(KIND=dp) :: dr1, dr2, dr3, dx, qt, r, r2, rt1, rt2, &
777 : rt3, rv1, rv2, rv3, rx, rx2, rx3, &
778 : sph_chrg_factor, Term, xs1, xs2, xs3
779 : REAL(KIND=dp), DIMENSION(3) :: ra
780 714 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: pot0_2
781 714 : REAL(KIND=dp), DIMENSION(:, :, :), POINTER :: grid2
782 : TYPE(qmmm_pot_type), POINTER :: pot
783 :
784 714 : CALL timeset(routineN, handle)
785 714 : n1 = grid%pw_grid%npts(1)
786 714 : n2 = grid%pw_grid%npts(2)
787 714 : n3 = grid%pw_grid%npts(3)
788 714 : dr1 = grid%pw_grid%dr(1)
789 714 : dr2 = grid%pw_grid%dr(2)
790 714 : dr3 = grid%pw_grid%dr(3)
791 7140 : gbo = grid%pw_grid%bounds
792 7140 : bo = grid%pw_grid%bounds_local
793 714 : grid2 => grid%array
794 714 : IF (par_scheme == do_par_atom) myind = 0
795 2010 : Radius: DO IRadTyp = 1, SIZE(pgfs)
796 1296 : pot => potentials(IRadTyp)%pot
797 1296 : dx = Pot%dx
798 1296 : pot0_2 => Pot%pot0_2
799 : !$OMP PARALLEL DO DEFAULT(NONE) &
800 : !$OMP SHARED(pot, par_scheme, para_env, mm_atom_index, mm_particles, dOmmOqm, mm_cell, qmmm_spherical_cutoff) &
801 : !$OMP SHARED(bo, gbo, dr1, dr2, dr3, grid2, shells, pot0_2, dx, mm_charges, IRadTyp) &
802 : !$OMP PRIVATE(myind, Imm, LIndMM, IndMM, ra, qt, sph_chrg_factor, rt1, rt2, rt3, my_k, my_j) &
803 2010 : !$OMP PRIVATE(rv1, rv2, rv3, rx2, rx3, r, r2, rx, Term, xs1, xs2, xs3, i, j, k, ix)
804 : Atoms: DO Imm = 1, SIZE(pot%mm_atom_index)
805 : IF (par_scheme == do_par_atom) THEN
806 : myind = Imm + (IRadTyp - 1)*SIZE(pot%mm_atom_index)
807 : IF (MOD(myind, para_env%num_pe) /= para_env%mepos) CYCLE
808 : END IF
809 : LIndMM = pot%mm_atom_index(Imm)
810 : IndMM = mm_atom_index(LIndMM)
811 : ra(:) = pbc(mm_particles(IndMM)%r - dOmmOqm, mm_cell) + dOmmOqm
812 : qt = mm_charges(LIndMM)
813 : IF (shells) &
814 : ra(:) = pbc(mm_particles(LIndMM)%r - dOmmOqm, mm_cell) + dOmmOqm
815 : ! Possible Spherical Cutoff
816 : IF (qmmm_spherical_cutoff(1) > 0.0_dp) THEN
817 : CALL spherical_cutoff_factor(qmmm_spherical_cutoff, ra, sph_chrg_factor)
818 : qt = qt*sph_chrg_factor
819 : END IF
820 : IF (ABS(qt) <= EPSILON(0.0_dp)) CYCLE Atoms
821 : rt1 = ra(1)
822 : rt2 = ra(2)
823 : rt3 = ra(3)
824 : LoopOnGrid: DO k = bo(1, 3), bo(2, 3)
825 : my_k = k - gbo(1, 3)
826 : xs3 = REAL(my_k, dp)*dr3
827 : my_j = bo(1, 2) - gbo(1, 2)
828 : xs2 = REAL(my_j, dp)*dr2
829 : rv3 = rt3 - xs3
830 : DO j = bo(1, 2), bo(2, 2)
831 : xs1 = (bo(1, 1) - gbo(1, 1))*dr1
832 : rv2 = rt2 - xs2
833 : DO i = bo(1, 1), bo(2, 1)
834 : rv1 = rt1 - xs1
835 : r2 = rv1*rv1 + rv2*rv2 + rv3*rv3
836 : r = SQRT(r2)
837 : ix = FLOOR(r/dx) + 1
838 : rx = (r - REAL(ix - 1, dp)*dx)/dx
839 : rx2 = rx*rx
840 : rx3 = rx2*rx
841 : Term = pot0_2(1, ix)*(1.0_dp - 3.0_dp*rx2 + 2.0_dp*rx3) &
842 : + pot0_2(2, ix)*(rx - 2.0_dp*rx2 + rx3) &
843 : + pot0_2(1, ix + 1)*(3.0_dp*rx2 - 2.0_dp*rx3) &
844 : + pot0_2(2, ix + 1)*(-rx2 + rx3)
845 : !$OMP ATOMIC
846 : grid2(i, j, k) = grid2(i, j, k) - Term*qt
847 : !$OMP END ATOMIC
848 : xs1 = xs1 + dr1
849 : END DO
850 : xs2 = xs2 + dr2
851 : END DO
852 : END DO LoopOnGrid
853 : END DO Atoms
854 : !$OMP END PARALLEL DO
855 : END DO Radius
856 714 : CALL timestop(handle)
857 714 : END SUBROUTINE qmmm_elec_with_gaussian_LR
858 :
859 : END MODULE qmmm_gpw_energy
|