1!--------------------------------------------------------------------------------------------------!
2!   CP2K: A general program to perform molecular dynamics simulations                              !
3!   Copyright (C) 2000 - 2019  CP2K developers group                                               !
4!--------------------------------------------------------------------------------------------------!
5
6! **************************************************************************************************
7!> \par History
8!>      05.2004 created [fawzi]
9!> \author Fawzi Mohamed
10! **************************************************************************************************
11MODULE qmmm_types_low
12   USE cp_eri_mme_interface,            ONLY: cp_eri_mme_finalize,&
13                                              cp_eri_mme_param
14   USE ewald_environment_types,         ONLY: ewald_env_release,&
15                                              ewald_environment_type
16   USE ewald_pw_types,                  ONLY: ewald_pw_release,&
17                                              ewald_pw_type
18   USE force_field_types,               ONLY: deallocate_inp_info,&
19                                              init_inp_info,&
20                                              input_info_type
21   USE input_constants,                 ONLY: do_eri_mme,&
22                                              do_qmmm_none
23   USE kinds,                           ONLY: dp
24   USE particle_types,                  ONLY: allocate_particle_set,&
25                                              deallocate_particle_set,&
26                                              particle_type
27   USE pw_grid_types,                   ONLY: pw_grid_type
28   USE pw_grids,                        ONLY: pw_grid_release
29   USE pw_pool_types,                   ONLY: pw_pool_give_back_pw,&
30                                              pw_pool_p_type,&
31                                              pw_pool_release,&
32                                              pw_pool_type,&
33                                              pw_pools_dealloc
34   USE pw_types,                        ONLY: pw_type
35   USE qmmm_gaussian_types,             ONLY: qmmm_gaussian_p_type
36#include "./base/base_uses.f90"
37
38   IMPLICIT NONE
39   PRIVATE
40
41   LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .TRUE.
42   CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qmmm_types_low'
43   INTEGER, SAVE, PRIVATE :: last_qmmm_env_id_nr = 0
44   INTEGER, PARAMETER, PUBLIC :: force_mixing_label_none = -1, &
45                                 force_mixing_label_QM_core_list = 10, &
46                                 force_mixing_label_QM_core = 9, &
47                                 force_mixing_label_QM_dynamics_list = 8, &
48                                 force_mixing_label_QM_dynamics = 7, &
49                                 force_mixing_label_buffer_list = 6, &
50                                 force_mixing_label_buffer = 5, &
51                                 force_mixing_label_termination = 4
52
53   PUBLIC :: qmmm_env_qm_type, qmmm_pot_type, qmmm_pot_p_type
54   PUBLIC :: qmmm_env_qm_release, qmmm_env_qm_create
55   PUBLIC :: qmmm_env_mm_type, qmmm_env_mm_create, qmmm_env_mm_retain, qmmm_env_mm_release
56   PUBLIC :: qmmm_imomm_link_type, qmmm_links_type
57   PUBLIC :: add_set_type, add_set_release, create_add_set_type
58   PUBLIC :: add_shell_type, create_add_shell_type
59   PUBLIC :: qmmm_per_pot_type, qmmm_per_pot_p_type
60
61! **************************************************************************************************
62!> \brief variables needed for QM/MM calculation in QM section
63!> \par History
64!>      05.2004 created [fawzi]
65!> \author Fawzi Mohamed
66!>      Teodoro Laino
67! **************************************************************************************************
68   TYPE gridlevel_info_type
69      INTEGER                                                 :: auxbas_grid
70      INTEGER                                                 :: coarser_grid
71   END TYPE gridlevel_info_type
72
73! **************************************************************************************************
74!> \brief Real Space Potential
75! **************************************************************************************************
76   TYPE qmmm_pot_type
77      REAL(KIND=dp), DIMENSION(:, :), POINTER :: Pot0_2
78      REAL(KIND=dp)   :: Rmax, Rmin, dx, Rc
79      INTEGER         :: npts
80      INTEGER, DIMENSION(:), POINTER :: mm_atom_index
81   END TYPE qmmm_pot_type
82
83   TYPE qmmm_pot_p_type
84      TYPE(qmmm_pot_type), POINTER :: pot
85   END TYPE qmmm_pot_p_type
86
87! **************************************************************************************************
88!> \brief Periodic Potential
89! **************************************************************************************************
90   TYPE qmmm_per_pot_type
91      REAL(KIND=dp), DIMENSION(:), POINTER :: lg, gx, gy, gz
92      REAL(KIND=dp)  :: Gmax, Fac(3)
93      INTEGER        :: Kmax(3), n_rep_real(3)
94      INTEGER, DIMENSION(:), POINTER :: mm_atom_index
95      TYPE(pw_pool_type), POINTER :: pw_pool
96      TYPE(pw_grid_type), POINTER :: pw_grid
97      TYPE(pw_type), POINTER :: TabLR
98   END TYPE qmmm_per_pot_type
99
100   TYPE qmmm_per_pot_p_type
101      TYPE(qmmm_per_pot_type), POINTER :: pot
102   END TYPE qmmm_per_pot_p_type
103
104! **************************************************************************************************
105!> \brief LINKs IMOMM
106! **************************************************************************************************
107   TYPE qmmm_imomm_link_type
108      INTEGER  :: qm_index, mm_index
109      REAL(KIND=dp) :: alpha
110   END TYPE qmmm_imomm_link_type
111
112   TYPE qmmm_imomm_link_p_type
113      TYPE(qmmm_imomm_link_type), POINTER :: link
114   END TYPE qmmm_imomm_link_p_type
115
116! **************************************************************************************************
117!> \brief LINKs PSEUDO
118! **************************************************************************************************
119   TYPE qmmm_pseudo_link_type
120      INTEGER  :: qm_index, mm_index
121   END TYPE qmmm_pseudo_link_type
122
123   TYPE qmmm_pseudo_link_p_type
124      TYPE(qmmm_pseudo_link_type), POINTER :: link
125   END TYPE qmmm_pseudo_link_p_type
126
127! **************************************************************************************************
128!> \brief LINKs summary
129! **************************************************************************************************
130   TYPE qmmm_links_type
131      TYPE(qmmm_imomm_link_p_type), DIMENSION(:), POINTER :: imomm
132      TYPE(qmmm_pseudo_link_p_type), DIMENSION(:), POINTER :: pseudo
133   END TYPE qmmm_links_type
134
135! **************************************************************************************************
136!> \brief ...
137! **************************************************************************************************
138   TYPE add_env_type
139      INTEGER       :: Index1, Index2
140      REAL(KIND=dp) :: alpha
141   END TYPE add_env_type
142
143! **************************************************************************************************
144!> \brief ...
145! **************************************************************************************************
146   TYPE add_set_type
147      INTEGER                                                 :: num_mm_atoms
148      TYPE(add_env_type), DIMENSION(:), POINTER              :: add_env
149      TYPE(particle_type), DIMENSION(:), POINTER              :: added_particles
150      INTEGER, DIMENSION(:), POINTER                   :: mm_atom_index
151      REAL(KIND=dp), DIMENSION(:), POINTER                    :: mm_atom_chrg
152      REAL(KIND=dp), DIMENSION(:), POINTER                    :: mm_el_pot_radius
153      REAL(KIND=dp), DIMENSION(:), POINTER                    :: mm_el_pot_radius_corr
154      TYPE(qmmm_pot_p_type), DIMENSION(:), POINTER            :: Potentials
155      TYPE(qmmm_per_pot_p_type), DIMENSION(:), POINTER        :: Per_Potentials
156      TYPE(qmmm_gaussian_p_type), DIMENSION(:), POINTER        :: pgfs
157   END TYPE add_set_type
158
159! **************************************************************************************************
160!> \brief parameters for core-shell model potentials
161! **************************************************************************************************
162   TYPE add_shell_type
163      INTEGER                                                 :: num_mm_atoms
164      TYPE(particle_type), DIMENSION(:), POINTER              :: added_particles
165      TYPE(particle_type), DIMENSION(:), POINTER              :: added_cores
166      INTEGER, DIMENSION(:), POINTER                   :: mm_core_index
167      REAL(KIND=dp), DIMENSION(:), POINTER                    :: mm_core_chrg
168      REAL(KIND=dp), DIMENSION(:), POINTER                    :: mm_el_pot_radius
169      REAL(KIND=dp), DIMENSION(:), POINTER                    :: mm_el_pot_radius_corr
170      TYPE(qmmm_pot_p_type), DIMENSION(:), POINTER            :: Potentials
171      TYPE(qmmm_per_pot_p_type), DIMENSION(:), POINTER        :: Per_Potentials
172      TYPE(qmmm_gaussian_p_type), DIMENSION(:), POINTER        :: pgfs
173   END TYPE add_shell_type
174
175! **************************************************************************************************
176!> \brief ...
177! **************************************************************************************************
178   TYPE image_charge_type
179      LOGICAL                                    :: all_mm
180      LOGICAL                                    :: coeff_iterative
181      LOGICAL                                    :: image_restart
182      INTEGER                                    :: state_image_matrix
183      INTEGER, DIMENSION(:), POINTER             :: image_mm_list
184      TYPE(particle_type), DIMENSION(:), POINTER :: particles_all
185      REAL(KIND=dp), DIMENSION(:, :), POINTER    :: image_forcesMM
186      REAL(KIND=dp)                              :: V0
187      REAL(KIND=dp)                              :: eta
188      INTEGER                                    :: image_matrix_method
189      TYPE(cp_eri_mme_param)                     :: eri_mme_param
190   END TYPE image_charge_type
191
192! **************************************************************************************************
193!> \brief ...
194! **************************************************************************************************
195   TYPE qmmm_env_qm_type
196      INTEGER :: ref_count, id_nr
197      LOGICAL                                                 :: center_qm_subsys
198      LOGICAL                                                 :: center_qm_subsys0, do_translate
199      LOGICAL                                                 :: center_qm_subsys_pbc_aware
200      LOGICAL                                                 :: do_force_mixing
201      LOGICAL                                                 :: compatibility
202      LOGICAL                                                 :: qmmm_link
203      LOGICAL                                                 :: move_mm_charges
204      LOGICAL                                                 :: add_mm_charges
205      LOGICAL                                                 :: periodic
206      LOGICAL                                                 :: multipole
207      LOGICAL                                                 :: image_charge
208      INTEGER                                                 :: par_scheme
209      INTEGER                                                 :: qmmm_coupl_type
210      INTEGER                                                 :: num_qm_atoms
211      INTEGER                                                 :: num_mm_atoms
212      INTEGER                                                 :: num_image_mm_atoms
213      REAL(KIND=dp)                                           :: eps_mm_rspace
214      REAL(KIND=dp), DIMENSION(3)                             :: dOmmOqm, utrasl, transl_v
215      REAL(KIND=dp), DIMENSION(2)                             :: spherical_cutoff
216      REAL(KIND=dp), DIMENSION(:), POINTER                    :: maxradius
217      INTEGER, DIMENSION(:), POINTER                    :: qm_atom_index
218      INTEGER, DIMENSION(:), POINTER                    :: mm_atom_index
219      INTEGER, DIMENSION(:), POINTER                    :: mm_link_atoms
220      REAL(KIND=dp), DIMENSION(:), POINTER                    :: mm_atom_chrg
221      REAL(KIND=dp), DIMENSION(:), POINTER                    :: mm_el_pot_radius
222      REAL(KIND=dp), DIMENSION(:), POINTER                    :: mm_el_pot_radius_corr
223      TYPE(qmmm_pot_p_type), DIMENSION(:), POINTER            :: Potentials
224      TYPE(qmmm_per_pot_p_type), DIMENSION(:), POINTER        :: Per_Potentials
225      TYPE(gridlevel_info_type)                               :: gridlevel_info
226      TYPE(qmmm_gaussian_p_type), DIMENSION(:), POINTER        :: pgfs
227      TYPE(pw_pool_p_type), DIMENSION(:), POINTER             :: aug_pools
228      TYPE(qmmm_links_type), POINTER                          :: qmmm_links
229      TYPE(add_set_type), POINTER                             :: added_charges
230      TYPE(add_shell_type), POINTER                           :: added_shells
231      TYPE(image_charge_type), POINTER                        :: image_charge_pot
232      TYPE(ewald_environment_type), POINTER                   :: ewald_env
233      TYPE(ewald_pw_type), POINTER                            :: ewald_pw
234   END TYPE qmmm_env_qm_type
235
236! **************************************************************************************************
237!> \brief ...
238! **************************************************************************************************
239   TYPE qmmm_env_mm_type
240      INTEGER :: ref_count, id_nr
241      LOGICAL                                                 :: qmmm_link
242      LOGICAL                                                 :: use_qmmm_ff
243      LOGICAL                                                 :: multiple_potential
244      INTEGER                                                 :: qmmm_coupl_type
245      INTEGER, DIMENSION(:), POINTER                   :: qm_atom_index
246      INTEGER, DIMENSION(:), POINTER                   :: mm_link_atoms
247      REAL(KIND=dp), DIMENSION(:), POINTER                   :: mm_link_scale_factor
248      REAL(KIND=dp), DIMENSION(:), POINTER                   :: fist_scale_charge_link
249      INTEGER, DIMENSION(:), POINTER                   :: qm_molecule_index
250      TYPE(input_info_type), POINTER                           :: inp_info
251   END TYPE qmmm_env_mm_type
252
253CONTAINS
254
255! **************************************************************************************************
256!> \brief ...
257!> \param qmmm_env ...
258!> \author Teodoro Laino
259! **************************************************************************************************
260   SUBROUTINE qmmm_env_mm_create(qmmm_env)
261      TYPE(qmmm_env_mm_type), POINTER                    :: qmmm_env
262
263      CHARACTER(len=*), PARAMETER :: routineN = 'qmmm_env_mm_create', &
264         routineP = moduleN//':'//routineN
265
266      CPASSERT(.NOT. ASSOCIATED(qmmm_env))
267      ALLOCATE (qmmm_env)
268      qmmm_env%ref_count = 1
269      last_qmmm_env_id_nr = last_qmmm_env_id_nr + 1
270      qmmm_env%id_nr = last_qmmm_env_id_nr
271      NULLIFY (qmmm_env%qm_atom_index, &
272               qmmm_env%qm_molecule_index, &
273               qmmm_env%mm_link_atoms, &
274               qmmm_env%mm_link_scale_factor, &
275               qmmm_env%fist_scale_charge_link, &
276               qmmm_env%inp_info)
277      qmmm_env%qmmm_coupl_type = do_qmmm_none
278      qmmm_env%qmmm_link = .FALSE.
279      qmmm_env%use_qmmm_ff = .FALSE.
280      ALLOCATE (qmmm_env%inp_info)
281      CALL init_inp_info(qmmm_env%inp_info)
282   END SUBROUTINE qmmm_env_mm_create
283
284! **************************************************************************************************
285!> \brief ...
286!> \param qmmm_env ...
287!> \author Teodoro Laino
288! **************************************************************************************************
289   SUBROUTINE qmmm_env_mm_retain(qmmm_env)
290      TYPE(qmmm_env_mm_type), POINTER                    :: qmmm_env
291
292      CHARACTER(len=*), PARAMETER :: routineN = 'qmmm_env_mm_retain', &
293         routineP = moduleN//':'//routineN
294
295      CPASSERT(ASSOCIATED(qmmm_env))
296      CPASSERT(qmmm_env%ref_count > 0)
297      qmmm_env%ref_count = qmmm_env%ref_count + 1
298   END SUBROUTINE qmmm_env_mm_retain
299
300! **************************************************************************************************
301!> \brief releases the given qmmm_env (see doc/ReferenceCounting.html)
302!> \param qmmm_env the object to release
303!> \author Fawzi Mohamed
304!>      Teodoro Laino
305! **************************************************************************************************
306   SUBROUTINE qmmm_env_mm_release(qmmm_env)
307      TYPE(qmmm_env_mm_type), POINTER                    :: qmmm_env
308
309      CHARACTER(len=*), PARAMETER :: routineN = 'qmmm_env_mm_release', &
310         routineP = moduleN//':'//routineN
311
312      IF (ASSOCIATED(qmmm_env)) THEN
313         CPASSERT(qmmm_env%ref_count > 0)
314         qmmm_env%ref_count = qmmm_env%ref_count - 1
315         IF (qmmm_env%ref_count == 0) THEN
316            IF (ASSOCIATED(qmmm_env%qm_atom_index)) THEN
317               DEALLOCATE (qmmm_env%qm_atom_index)
318            END IF
319            IF (ASSOCIATED(qmmm_env%qm_molecule_index)) THEN
320               DEALLOCATE (qmmm_env%qm_molecule_index)
321            END IF
322            IF (ASSOCIATED(qmmm_env%mm_link_atoms)) THEN
323               DEALLOCATE (qmmm_env%mm_link_atoms)
324            END IF
325            IF (ASSOCIATED(qmmm_env%mm_link_scale_factor)) THEN
326               DEALLOCATE (qmmm_env%mm_link_scale_factor)
327            END IF
328            IF (ASSOCIATED(qmmm_env%fist_scale_charge_link)) THEN
329               DEALLOCATE (qmmm_env%fist_scale_charge_link)
330            END IF
331            IF (ASSOCIATED(qmmm_env%inp_info)) THEN
332               CALL deallocate_inp_info(qmmm_env%inp_info)
333               DEALLOCATE (qmmm_env%inp_info)
334            END IF
335
336            DEALLOCATE (qmmm_env)
337         END IF
338      END IF
339      NULLIFY (qmmm_env)
340   END SUBROUTINE qmmm_env_mm_release
341
342! **************************************************************************************************
343!> \brief ...
344!> \param qmmm_env ...
345!> \author Fawzi Mohamed
346! **************************************************************************************************
347   SUBROUTINE qmmm_env_qm_create(qmmm_env)
348      TYPE(qmmm_env_qm_type), POINTER                    :: qmmm_env
349
350      CHARACTER(len=*), PARAMETER :: routineN = 'qmmm_env_qm_create', &
351         routineP = moduleN//':'//routineN
352
353      CPASSERT(.NOT. ASSOCIATED(qmmm_env))
354      ALLOCATE (qmmm_env)
355      qmmm_env%ref_count = 1
356      last_qmmm_env_id_nr = last_qmmm_env_id_nr + 1
357      qmmm_env%id_nr = last_qmmm_env_id_nr
358      NULLIFY (qmmm_env%qm_atom_index, qmmm_env%mm_link_atoms, &
359               qmmm_env%mm_atom_index, qmmm_env%mm_atom_chrg, &
360               qmmm_env%pgfs, qmmm_env%maxradius, &
361               qmmm_env%aug_pools, qmmm_env%potentials, &
362               qmmm_env%qmmm_links, qmmm_env%added_charges, &
363               qmmm_env%per_potentials, qmmm_env%image_charge_pot, &
364               qmmm_env%added_shells)
365      NULLIFY (qmmm_env%ewald_env, qmmm_env%ewald_pw)
366      qmmm_env%do_translate = .TRUE.
367      qmmm_env%center_qm_subsys = .TRUE.
368      qmmm_env%center_qm_subsys0 = .TRUE.
369      qmmm_env%center_qm_subsys_pbc_aware = .FALSE.
370      qmmm_env%do_force_mixing = .FALSE.
371      qmmm_env%compatibility = .TRUE.
372      qmmm_env%qmmm_link = .FALSE.
373      qmmm_env%add_mm_charges = .FALSE.
374      qmmm_env%move_mm_charges = .FALSE.
375      qmmm_env%periodic = .FALSE.
376      qmmm_env%multipole = .FALSE.
377      qmmm_env%image_charge = .FALSE.
378      qmmm_env%qmmm_coupl_type = do_qmmm_none
379      qmmm_env%num_qm_atoms = 0
380      qmmm_env%num_mm_atoms = 0
381      qmmm_env%num_image_mm_atoms = 0
382      qmmm_env%gridlevel_info%auxbas_grid = 0
383      qmmm_env%gridlevel_info%coarser_grid = 0
384      CALL create_add_set_type(qmmm_env%added_charges, ndim=0)
385      !CALL create_add_shell_type(qmmm_env%added_shells, ndim=0)
386      CALL create_image_charge_type(qmmm_env%image_charge_pot)
387   END SUBROUTINE qmmm_env_qm_create
388
389! **************************************************************************************************
390!> \brief releases the given qmmm_env (see doc/ReferenceCounting.html)
391!> \param qmmm_env the object to release
392!> \author Fawzi Mohamed
393!>      Teodoro Laino
394! **************************************************************************************************
395   SUBROUTINE qmmm_env_qm_release(qmmm_env)
396      TYPE(qmmm_env_qm_type), POINTER                    :: qmmm_env
397
398      CHARACTER(len=*), PARAMETER :: routineN = 'qmmm_env_qm_release', &
399         routineP = moduleN//':'//routineN
400
401      IF (ASSOCIATED(qmmm_env)) THEN
402         CPASSERT(qmmm_env%ref_count > 0)
403         qmmm_env%ref_count = qmmm_env%ref_count - 1
404         IF (qmmm_env%ref_count == 0) THEN
405            IF (ASSOCIATED(qmmm_env%qm_atom_index)) THEN
406               DEALLOCATE (qmmm_env%qm_atom_index)
407            END IF
408            IF (ASSOCIATED(qmmm_env%maxradius)) THEN
409               DEALLOCATE (qmmm_env%maxradius)
410            END IF
411            IF (ASSOCIATED(qmmm_env%mm_atom_index)) THEN
412               DEALLOCATE (qmmm_env%mm_atom_index)
413            END IF
414            IF (ASSOCIATED(qmmm_env%mm_link_atoms)) THEN
415               DEALLOCATE (qmmm_env%mm_link_atoms)
416            END IF
417            IF (ASSOCIATED(qmmm_env%mm_atom_chrg)) THEN
418               DEALLOCATE (qmmm_env%mm_atom_chrg)
419            END IF
420            IF (ASSOCIATED(qmmm_env%mm_el_pot_radius)) THEN
421               DEALLOCATE (qmmm_env%mm_el_pot_radius)
422            END IF
423            IF (ASSOCIATED(qmmm_env%mm_el_pot_radius_corr)) THEN
424               DEALLOCATE (qmmm_env%mm_el_pot_radius_corr)
425            END IF
426            IF (ASSOCIATED(qmmm_env%pgfs)) THEN
427               CALL pgfs_release(qmmm_env%pgfs)
428               DEALLOCATE (qmmm_env%pgfs)
429            END IF
430            IF (ASSOCIATED(qmmm_env%Potentials)) THEN
431               CALL qmmm_pot_type_dealloc(qmmm_env%Potentials)
432               DEALLOCATE (qmmm_env%Potentials)
433            END IF
434            IF (ASSOCIATED(qmmm_env%Per_Potentials)) THEN
435               CALL qmmm_per_pot_type_dealloc(qmmm_env%Per_Potentials)
436               DEALLOCATE (qmmm_env%Per_Potentials)
437            END IF
438            IF (ASSOCIATED(qmmm_env%aug_pools)) THEN
439               CALL pw_pools_dealloc(qmmm_env%aug_pools)
440            END IF
441            IF (ASSOCIATED(qmmm_env%qmmm_links)) THEN
442               CALL qmmm_links_dealloc(qmmm_env%qmmm_links)
443            END IF
444            IF (ASSOCIATED(qmmm_env%added_charges)) THEN
445               CALL add_set_release(qmmm_env%added_charges)
446            END IF
447            IF (ASSOCIATED(qmmm_env%added_shells)) THEN
448               CALL add_shell_release(qmmm_env%added_shells)
449            END IF
450            IF (ASSOCIATED(qmmm_env%image_charge_pot)) THEN
451               IF (qmmm_env%image_charge) THEN
452                  IF (qmmm_env%image_charge_pot%image_matrix_method .EQ. do_eri_mme) THEN
453                     CALL cp_eri_mme_finalize(qmmm_env%image_charge_pot%eri_mme_param)
454                  ENDIF
455               ENDIF
456               CALL qmmm_image_charge_dealloc(qmmm_env%image_charge_pot)
457            END IF
458            IF (ASSOCIATED(qmmm_env%ewald_env)) THEN
459               CALL ewald_env_release(qmmm_env%ewald_env)
460            END IF
461            IF (ASSOCIATED(qmmm_env%ewald_pw)) THEN
462               CALL ewald_pw_release(qmmm_env%ewald_pw)
463            END IF
464            DEALLOCATE (qmmm_env)
465         END IF
466      END IF
467      NULLIFY (qmmm_env)
468   END SUBROUTINE qmmm_env_qm_release
469
470! **************************************************************************************************
471!> \brief deallocates the pgfs type
472!> \param pgfs ...
473!> \author Teodoro Laino
474! **************************************************************************************************
475   SUBROUTINE pgfs_release(pgfs)
476      TYPE(qmmm_gaussian_p_type), DIMENSION(:), POINTER  :: pgfs
477
478      CHARACTER(len=*), PARAMETER :: routineN = 'pgfs_release', routineP = moduleN//':'//routineN
479
480      INTEGER                                            :: I
481
482      DO I = 1, SIZE(pgfs)
483         IF (ASSOCIATED(pgfs(I)%pgf)) THEN
484            IF (ASSOCIATED(pgfs(I)%pgf%Ak)) THEN
485               DEALLOCATE (pgfs(I)%pgf%Ak)
486            END IF
487            IF (ASSOCIATED(pgfs(I)%pgf%Gk)) THEN
488               DEALLOCATE (pgfs(I)%pgf%Gk)
489            END IF
490            IF (ASSOCIATED(pgfs(I)%pgf%grid_level)) THEN
491               DEALLOCATE (pgfs(I)%pgf%grid_level)
492            END IF
493            DEALLOCATE (pgfs(I)%pgf)
494         END IF
495      END DO
496   END SUBROUTINE pgfs_release
497
498! **************************************************************************************************
499!> \brief deallocates the qmmm_links structure
500!> \param qmmm_links ...
501!> \author Teodoro Laino
502! **************************************************************************************************
503   SUBROUTINE qmmm_links_dealloc(qmmm_links)
504      TYPE(qmmm_links_type), POINTER                     :: qmmm_links
505
506      CHARACTER(len=*), PARAMETER :: routineN = 'qmmm_links_dealloc', &
507         routineP = moduleN//':'//routineN
508
509      INTEGER                                            :: I
510
511      IF (ASSOCIATED(qmmm_links%imomm)) THEN
512         DO i = 1, SIZE(qmmm_links%imomm)
513            IF (ASSOCIATED(qmmm_links%imomm(i)%link)) DEALLOCATE (qmmm_links%imomm(i)%link)
514         END DO
515         DEALLOCATE (qmmm_links%imomm)
516      END IF
517      IF (ASSOCIATED(qmmm_links%pseudo)) THEN
518         DO i = 1, SIZE(qmmm_links%pseudo)
519            IF (ASSOCIATED(qmmm_links%pseudo(i)%link)) DEALLOCATE (qmmm_links%pseudo(i)%link)
520         END DO
521         DEALLOCATE (qmmm_links%pseudo)
522      END IF
523      DEALLOCATE (qmmm_links)
524   END SUBROUTINE qmmm_links_dealloc
525
526! ****************************************************************************
527!> \brief deallocates the image_charge_pot structure
528!> \param image_charge_pot ...
529!> \author Dorothea Golze
530! **************************************************************************************************
531   SUBROUTINE qmmm_image_charge_dealloc(image_charge_pot)
532      TYPE(image_charge_type), POINTER                   :: image_charge_pot
533
534      CHARACTER(len=*), PARAMETER :: routineN = 'qmmm_image_charge_dealloc', &
535         routineP = moduleN//':'//routineN
536
537      IF (ASSOCIATED(image_charge_pot)) THEN
538         IF (ASSOCIATED(image_charge_pot%image_mm_list)) THEN
539            IF (.NOT. image_charge_pot%all_mm) THEN
540               DEALLOCATE (image_charge_pot%image_mm_list)
541            END IF
542         END IF
543         IF (ASSOCIATED(image_charge_pot%image_forcesMM)) THEN
544            DEALLOCATE (image_charge_pot%image_forcesMM)
545         END IF
546         DEALLOCATE (image_charge_pot)
547      END IF
548   END SUBROUTINE qmmm_image_charge_dealloc
549
550! **************************************************************************************************
551!> \brief deallocates the qmmm_pot_type structure
552!> \param Potentials ...
553!> \author Teodoro Laino
554! **************************************************************************************************
555   SUBROUTINE qmmm_pot_type_dealloc(Potentials)
556      TYPE(qmmm_pot_p_type), DIMENSION(:), POINTER       :: Potentials
557
558      CHARACTER(len=*), PARAMETER :: routineN = 'qmmm_pot_type_dealloc', &
559         routineP = moduleN//':'//routineN
560
561      INTEGER                                            :: I
562
563      DO I = 1, SIZE(Potentials)
564         IF (ASSOCIATED(Potentials(I)%Pot)) THEN
565            IF (ASSOCIATED(Potentials(I)%Pot%pot0_2)) THEN
566               DEALLOCATE (Potentials(I)%Pot%pot0_2)
567            END IF
568            IF (ASSOCIATED(Potentials(I)%Pot%mm_atom_index)) THEN
569               DEALLOCATE (Potentials(I)%Pot%mm_atom_index)
570            END IF
571            DEALLOCATE (Potentials(I)%Pot)
572         END IF
573      END DO
574
575   END SUBROUTINE qmmm_pot_type_dealloc
576
577! **************************************************************************************************
578!> \brief deallocates the qmmm_per_pot_type structure
579!>      for QM/MM periodic boundary conditions
580!> \param Per_Potentials ...
581!> \author Teodoro Laino
582! **************************************************************************************************
583   SUBROUTINE qmmm_per_pot_type_dealloc(Per_Potentials)
584      TYPE(qmmm_per_pot_p_type), DIMENSION(:), POINTER   :: Per_Potentials
585
586      CHARACTER(len=*), PARAMETER :: routineN = 'qmmm_per_pot_type_dealloc', &
587         routineP = moduleN//':'//routineN
588
589      INTEGER                                            :: I
590
591      DO I = 1, SIZE(Per_Potentials)
592         IF (ASSOCIATED(Per_Potentials(I)%Pot)) THEN
593            IF (ASSOCIATED(Per_Potentials(I)%Pot%LG)) THEN
594               DEALLOCATE (Per_Potentials(I)%Pot%LG)
595            END IF
596            IF (ASSOCIATED(Per_Potentials(I)%Pot%gx)) THEN
597               DEALLOCATE (Per_Potentials(I)%Pot%gx)
598            END IF
599            IF (ASSOCIATED(Per_Potentials(I)%Pot%gy)) THEN
600               DEALLOCATE (Per_Potentials(I)%Pot%gy)
601            END IF
602            IF (ASSOCIATED(Per_Potentials(I)%Pot%gz)) THEN
603               DEALLOCATE (Per_Potentials(I)%Pot%gz)
604            END IF
605            IF (ASSOCIATED(Per_Potentials(I)%Pot%mm_atom_index)) THEN
606               DEALLOCATE (Per_Potentials(I)%Pot%mm_atom_index)
607            END IF
608            IF (ASSOCIATED(Per_Potentials(I)%Pot%TabLR)) THEN
609               CALL pw_pool_give_back_pw(Per_Potentials(I)%Pot%pw_pool, Per_Potentials(I)%Pot%TabLR)
610            END IF
611            IF (ASSOCIATED(Per_Potentials(I)%Pot%pw_pool)) THEN
612               CALL pw_pool_release(Per_Potentials(I)%Pot%pw_pool)
613               CPASSERT(.NOT. ASSOCIATED(Per_Potentials(I)%Pot%pw_pool))
614            END IF
615            IF (ASSOCIATED(Per_Potentials(I)%Pot%pw_grid)) THEN
616               CALL pw_grid_release(Per_Potentials(I)%Pot%pw_grid)
617               CPASSERT(.NOT. ASSOCIATED(Per_Potentials(I)%Pot%pw_grid))
618            END IF
619            DEALLOCATE (Per_Potentials(I)%Pot)
620         END IF
621      END DO
622
623   END SUBROUTINE qmmm_per_pot_type_dealloc
624
625! **************************************************************************************************
626!> \brief deallocates the add_set_release
627!> \param added_charges ...
628!> \author Teodoro Laino
629! **************************************************************************************************
630   SUBROUTINE add_set_release(added_charges)
631      TYPE(add_set_type), POINTER                        :: added_charges
632
633      CHARACTER(len=*), PARAMETER :: routineN = 'add_set_release', &
634         routineP = moduleN//':'//routineN
635
636      IF (ASSOCIATED(added_charges)) THEN
637         IF (ASSOCIATED(added_charges%add_env)) THEN
638            DEALLOCATE (added_charges%add_env)
639         END IF
640         IF (ASSOCIATED(added_charges%added_particles)) THEN
641            CALL deallocate_particle_set(added_charges%added_particles)
642         END IF
643         IF (ASSOCIATED(added_charges%mm_atom_index)) THEN
644            DEALLOCATE (added_charges%mm_atom_index)
645         END IF
646         IF (ASSOCIATED(added_charges%mm_atom_chrg)) THEN
647            DEALLOCATE (added_charges%mm_atom_chrg)
648         END IF
649         IF (ASSOCIATED(added_charges%mm_el_pot_radius)) THEN
650            DEALLOCATE (added_charges%mm_el_pot_radius)
651         END IF
652         IF (ASSOCIATED(added_charges%mm_el_pot_radius_corr)) THEN
653            DEALLOCATE (added_charges%mm_el_pot_radius_corr)
654         END IF
655         IF (ASSOCIATED(added_charges%Potentials)) THEN
656            CALL qmmm_pot_type_dealloc(added_charges%Potentials)
657            DEALLOCATE (added_charges%Potentials)
658         END IF
659         IF (ASSOCIATED(added_charges%Per_Potentials)) THEN
660            CALL qmmm_per_pot_type_dealloc(added_charges%Per_Potentials)
661            DEALLOCATE (added_charges%Per_Potentials)
662         END IF
663         IF (ASSOCIATED(added_charges%pgfs)) THEN
664            CALL pgfs_release(added_charges%pgfs)
665            DEALLOCATE (added_charges%pgfs)
666         END IF
667         DEALLOCATE (added_charges)
668      END IF
669   END SUBROUTINE add_set_release
670
671! **************************************************************************************************
672!> \brief deallocates the add_shell_release
673!> \param added_shells ...
674!> \author MattW
675! **************************************************************************************************
676   SUBROUTINE add_shell_release(added_shells)
677
678      TYPE(add_shell_type), POINTER                      :: added_shells
679
680      CHARACTER(len=*), PARAMETER :: routineN = 'add_shell_release', &
681         routineP = moduleN//':'//routineN
682
683      IF (ASSOCIATED(added_shells)) THEN
684         IF (ASSOCIATED(added_shells%added_particles)) THEN
685            !XXXFIST should clean up shell particles
686            NULLIFY (added_shells%added_particles)
687            NULLIFY (added_shells%added_cores)
688            !CALL deallocate_particle_set(added_shells%added_particles)
689         END IF
690         IF (ASSOCIATED(added_shells%mm_core_index)) THEN
691            DEALLOCATE (added_shells%mm_core_index)
692         END IF
693         IF (ASSOCIATED(added_shells%mm_core_chrg)) THEN
694            DEALLOCATE (added_shells%mm_core_chrg)
695         END IF
696         IF (ASSOCIATED(added_shells%mm_el_pot_radius)) THEN
697            DEALLOCATE (added_shells%mm_el_pot_radius)
698         END IF
699         IF (ASSOCIATED(added_shells%mm_el_pot_radius_corr)) THEN
700            DEALLOCATE (added_shells%mm_el_pot_radius_corr)
701         END IF
702         IF (ASSOCIATED(added_shells%Potentials)) THEN
703            CALL qmmm_pot_type_dealloc(added_shells%Potentials)
704            DEALLOCATE (added_shells%Potentials)
705         END IF
706         IF (ASSOCIATED(added_shells%Per_Potentials)) THEN
707            CALL qmmm_per_pot_type_dealloc(added_shells%Per_Potentials)
708            DEALLOCATE (added_shells%Per_Potentials)
709         END IF
710         IF (ASSOCIATED(added_shells%pgfs)) THEN
711            CALL pgfs_release(added_shells%pgfs)
712            DEALLOCATE (added_shells%pgfs)
713         END IF
714         DEALLOCATE (added_shells)
715      END IF
716
717   END SUBROUTINE add_shell_release
718
719! **************************************************************************************************
720!> \brief creates the add_set_type structure
721!> \param added_charges ...
722!> \param ndim ...
723!> \author Teodoro Laino
724! **************************************************************************************************
725   SUBROUTINE create_add_set_type(added_charges, ndim)
726      TYPE(add_set_type), POINTER                        :: added_charges
727      INTEGER, INTENT(IN)                                :: ndim
728
729      CHARACTER(len=*), PARAMETER :: routineN = 'create_add_set_type', &
730         routineP = moduleN//':'//routineN
731
732      IF (ASSOCIATED(added_charges)) CALL add_set_release(added_charges)
733      ALLOCATE (added_charges)
734
735      NULLIFY (added_charges%add_env, &
736               added_charges%mm_atom_index, &
737               added_charges%added_particles, &
738               added_charges%mm_atom_chrg, &
739               added_charges%mm_el_pot_radius, &
740               added_charges%mm_el_pot_radius_corr, &
741               added_charges%potentials, &
742               added_charges%per_potentials, &
743               added_charges%pgfs)
744
745      added_charges%num_mm_atoms = ndim
746      IF (ndim == 0) RETURN
747      !
748      ! Allocate leave out just potential and pgfs...
749      !
750      ALLOCATE (added_charges%add_env(ndim))
751      CALL allocate_particle_set(added_charges%added_particles, ndim)
752      ALLOCATE (added_charges%mm_atom_index(ndim))
753      ALLOCATE (added_charges%mm_atom_chrg(ndim))
754      ALLOCATE (added_charges%mm_el_pot_radius(ndim))
755      ALLOCATE (added_charges%mm_el_pot_radius_corr(ndim))
756   END SUBROUTINE create_add_set_type
757
758! **************************************************************************************************
759!> \brief creates the add_shell_type structure
760!> \param added_shells ...
761!> \param ndim ...
762!> \author Teodoro Laino
763! **************************************************************************************************
764
765   SUBROUTINE create_add_shell_type(added_shells, ndim)
766      TYPE(add_shell_type), POINTER                      :: added_shells
767      INTEGER, INTENT(IN)                                :: ndim
768
769      CHARACTER(len=*), PARAMETER :: routineN = 'create_add_shell_type', &
770         routineP = moduleN//':'//routineN
771
772      IF (ASSOCIATED(added_shells)) CALL add_shell_release(added_shells)
773      ALLOCATE (added_shells)
774
775      NULLIFY (added_shells%mm_core_index, &
776               added_shells%added_particles, &
777               added_shells%added_cores, &
778               added_shells%mm_core_chrg, &
779               added_shells%mm_el_pot_radius, &
780               added_shells%mm_el_pot_radius_corr, &
781               added_shells%potentials, &
782               added_shells%per_potentials, &
783               added_shells%pgfs)
784
785      added_shells%num_mm_atoms = ndim
786      IF (ndim == 0) RETURN
787      !
788      ! Allocate leave out just potential and pgfs...
789      !
790      ALLOCATE (added_shells%mm_core_index(ndim))
791      ALLOCATE (added_shells%mm_core_chrg(ndim))
792      ALLOCATE (added_shells%mm_el_pot_radius(ndim))
793      ALLOCATE (added_shells%mm_el_pot_radius_corr(ndim))
794
795   END SUBROUTINE create_add_shell_type
796
797! **************************************************************************************************
798!> \brief creates the image_charge_type structure
799!> \param image_charge_pot ...
800!> \author Dorothea Golze
801! **************************************************************************************************
802   SUBROUTINE create_image_charge_type(image_charge_pot)
803      TYPE(image_charge_type), POINTER                   :: image_charge_pot
804
805      CHARACTER(len=*), PARAMETER :: routineN = 'create_image_charge_type', &
806         routineP = moduleN//':'//routineN
807
808      IF (ASSOCIATED(image_charge_pot)) CALL qmmm_image_charge_dealloc(image_charge_pot)
809      ALLOCATE (image_charge_pot)
810
811      NULLIFY (image_charge_pot%image_mm_list, &
812               image_charge_pot%particles_all, &
813               image_charge_pot%image_forcesMM)
814
815      image_charge_pot%all_mm = .TRUE.
816      image_charge_pot%coeff_iterative = .FALSE.
817      image_charge_pot%image_restart = .FALSE.
818
819   END SUBROUTINE create_image_charge_type
820
821END MODULE qmmm_types_low
822