1!--------------------------------------------------------------------------------------------------!
2!   CP2K: A general program to perform molecular dynamics simulations                              !
3!   Copyright (C) 2000 - 2019  CP2K developers group                                               !
4!--------------------------------------------------------------------------------------------------!
5
6! **************************************************************************************************
7!> \brief Basic container type for QM/MM.
8!> \author Ole Schuett
9! **************************************************************************************************
10MODULE qmmm_types
11   USE cp_subsys_types,                 ONLY: cp_subsys_type
12   USE fist_energy_types,               ONLY: fist_energy_type
13   USE fist_environment_types,          ONLY: fist_env_get,&
14                                              fist_env_release,&
15                                              fist_environment_type
16   USE kinds,                           ONLY: dp
17   USE qmmm_types_low,                  ONLY: qmmm_env_qm_release,&
18                                              qmmm_env_qm_type
19   USE qs_energy_types,                 ONLY: qs_energy_type
20   USE qs_environment_types,            ONLY: get_qs_env,&
21                                              qs_env_release,&
22                                              qs_environment_type
23#include "./base/base_uses.f90"
24
25   IMPLICIT NONE
26   PRIVATE
27
28   CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qmmm_types'
29
30   PUBLIC :: qmmm_env_type, qmmm_env_retain, qmmm_env_release, qmmm_env_get
31
32   TYPE qmmm_env_type
33      INTEGER                                                 :: ref_count = 1
34      TYPE(qs_environment_type), POINTER                      :: qs_env => Null()
35      TYPE(fist_environment_type), POINTER                    :: fist_env => Null()
36      TYPE(qmmm_env_qm_type), POINTER                         :: qm => Null()
37   END TYPE qmmm_env_type
38
39CONTAINS
40
41! **************************************************************************************************
42!> \brief ...
43!> \param qmmm_env ...
44!> \param subsys ...
45!> \param potential_energy ...
46!> \param kinetic_energy ...
47! **************************************************************************************************
48   SUBROUTINE qmmm_env_get(qmmm_env, subsys, potential_energy, kinetic_energy)
49      TYPE(qmmm_env_type), POINTER                       :: qmmm_env
50      TYPE(cp_subsys_type), OPTIONAL, POINTER            :: subsys
51      REAL(KIND=dp), INTENT(OUT), OPTIONAL               :: potential_energy, kinetic_energy
52
53      CHARACTER(len=*), PARAMETER :: routineN = 'qmmm_env_get', routineP = moduleN//':'//routineN
54
55      TYPE(fist_energy_type), POINTER                    :: thermo
56      TYPE(qs_energy_type), POINTER                      :: qs_energy
57
58      NULLIFY (qs_energy, thermo)
59
60      CPASSERT(ASSOCIATED(qmmm_env))
61      CPASSERT(qmmm_env%ref_count > 0)
62
63      IF (PRESENT(kinetic_energy)) THEN
64         CALL fist_env_get(qmmm_env%fist_env, thermo=thermo)
65         kinetic_energy = thermo%kin
66      END IF
67      IF (PRESENT(subsys)) THEN
68         CALL fist_env_get(qmmm_env%fist_env, subsys=subsys)
69      ENDIF
70      IF (PRESENT(potential_energy)) THEN
71         ! get the underlying energies from primary subsys.  This is the only subsys
72         ! for conventional QM/MM, and force-mixing knows to put relevant energy there.
73         CALL fist_env_get(qmmm_env%fist_env, thermo=thermo)
74         CALL get_qs_env(qmmm_env%qs_env, energy=qs_energy)
75         potential_energy = thermo%pot + qs_energy%total
76      ENDIF
77   END SUBROUTINE qmmm_env_get
78
79! **************************************************************************************************
80!> \brief releases the given qmmm_env (see doc/ReferenceCounting.html)
81!> \param qmmm_env the object to release
82!> \author Ole Schuett
83! **************************************************************************************************
84   SUBROUTINE qmmm_env_release(qmmm_env)
85      TYPE(qmmm_env_type), POINTER                       :: qmmm_env
86
87      CHARACTER(len=*), PARAMETER :: routineN = 'qmmm_env_release', &
88         routineP = moduleN//':'//routineN
89
90      IF (ASSOCIATED(qmmm_env)) THEN
91         CPASSERT(qmmm_env%ref_count > 0)
92         qmmm_env%ref_count = qmmm_env%ref_count - 1
93         IF (qmmm_env%ref_count == 0) THEN
94            CALL qs_env_release(qmmm_env%qs_env)
95            CALL qmmm_env_qm_release(qmmm_env%qm)
96            CALL fist_env_release(qmmm_env%fist_env)
97            DEALLOCATE (qmmm_env)
98         END IF
99      END IF
100      NULLIFY (qmmm_env)
101   END SUBROUTINE qmmm_env_release
102
103! **************************************************************************************************
104!> \brief ...
105!> \param qmmm_env ...
106!> \author Ole Schuett
107! **************************************************************************************************
108   SUBROUTINE qmmm_env_retain(qmmm_env)
109      TYPE(qmmm_env_type), POINTER                       :: qmmm_env
110
111      CHARACTER(len=*), PARAMETER :: routineN = 'qmmm_env_retain', &
112         routineP = moduleN//':'//routineN
113
114      CPASSERT(ASSOCIATED(qmmm_env))
115      CPASSERT(qmmm_env%ref_count > 0)
116      qmmm_env%ref_count = qmmm_env%ref_count + 1
117   END SUBROUTINE qmmm_env_retain
118
119END MODULE qmmm_types
120