1!--------------------------------------------------------------------------------------------------!
2!   CP2K: A general program to perform molecular dynamics simulations                              !
3!   Copyright (C) 2000 - 2019  CP2K developers group                                               !
4!--------------------------------------------------------------------------------------------------!
5
6! **************************************************************************************************
7!> \brief types of  preconditioners
8!> \par History
9!>      Separate types from construction and application
10!> \author Joost VandeVondele (09.2002)
11! **************************************************************************************************
12MODULE preconditioner_types
13   USE cp_blacs_env,                    ONLY: cp_blacs_env_release,&
14                                              cp_blacs_env_retain,&
15                                              cp_blacs_env_type
16   USE cp_fm_types,                     ONLY: cp_fm_release,&
17                                              cp_fm_type
18   USE cp_para_env,                     ONLY: cp_para_env_release,&
19                                              cp_para_env_retain
20   USE cp_para_types,                   ONLY: cp_para_env_type
21   USE dbcsr_api,                       ONLY: dbcsr_deallocate_matrix,&
22                                              dbcsr_p_type,&
23                                              dbcsr_release_p,&
24                                              dbcsr_type
25   USE input_constants,                 ONLY: cholesky_reduce,&
26                                              ot_precond_solver_default
27   USE kinds,                           ONLY: dp
28#include "./base/base_uses.f90"
29
30   IMPLICIT NONE
31
32   PRIVATE
33
34   CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'preconditioner_types'
35
36   PUBLIC  :: preconditioner_type, preconditioner_p_type
37   PUBLIC  :: init_preconditioner
38   PUBLIC  :: preconditioner_in_use
39   PUBLIC  :: destroy_preconditioner
40
41! **************************************************************************************************
42   TYPE preconditioner_type
43!    PRIVATE
44      TYPE(dbcsr_type), POINTER :: sparse_matrix
45      TYPE(cp_fm_type), POINTER :: fm
46      TYPE(dbcsr_type), POINTER           :: dbcsr_matrix
47      TYPE(dbcsr_type), POINTER           :: max_ev_vector
48      TYPE(dbcsr_type), POINTER           :: min_ev_vector
49      TYPE(dbcsr_p_type), POINTER, DIMENSION(:) :: inverse_history
50      TYPE(cp_para_env_type), POINTER   :: para_env
51      TYPE(cp_blacs_env_type), POINTER   :: ctxt
52      INTEGER :: in_use, solver, ihistory, cholesky_use
53      REAL(KIND=dp), DIMENSION(:), POINTER :: occ_evals, full_evals
54      REAL(KIND=dp) :: energy_gap
55      REAL(KIND=dp) :: condition_num
56   END TYPE preconditioner_type
57
58! **************************************************************************************************
59   TYPE preconditioner_p_type
60      TYPE(preconditioner_type), POINTER :: preconditioner
61   END TYPE preconditioner_p_type
62
63CONTAINS
64
65! **************************************************************************************************
66
67! **************************************************************************************************
68!> \brief ...
69!> \param preconditioner ...
70!> \return ...
71! **************************************************************************************************
72   FUNCTION preconditioner_in_use(preconditioner)
73      TYPE(preconditioner_type)                          :: preconditioner
74      LOGICAL                                            :: preconditioner_in_use
75
76      preconditioner_in_use = .NOT. (preconditioner%in_use .EQ. 0)
77   END FUNCTION
78
79! **************************************************************************************************
80!> \brief ...
81!> \param preconditioner_env ...
82!> \param para_env ...
83!> \param blacs_env ...
84! **************************************************************************************************
85   SUBROUTINE init_preconditioner(preconditioner_env, para_env, blacs_env)
86
87      TYPE(preconditioner_type)                          :: preconditioner_env
88      TYPE(cp_para_env_type), POINTER                    :: para_env
89      TYPE(cp_blacs_env_type), POINTER                   :: blacs_env
90
91      NULLIFY (preconditioner_env%sparse_matrix)
92      NULLIFY (preconditioner_env%fm)
93      NULLIFY (preconditioner_env%dbcsr_matrix)
94      NULLIFY (preconditioner_env%occ_evals)
95      NULLIFY (preconditioner_env%full_evals)
96      NULLIFY (preconditioner_env%inverse_history)
97      NULLIFY (preconditioner_env%max_ev_vector)
98      NULLIFY (preconditioner_env%min_ev_vector)
99      preconditioner_env%solver = ot_precond_solver_default
100      preconditioner_env%para_env => para_env
101      preconditioner_env%ctxt => blacs_env
102      !inverse is used for filtering in update set it to something huge to
103      ! avoid filtering if the information is not available
104      preconditioner_env%condition_num = -1.0_dp
105      preconditioner_env%ihistory = 0
106
107      CALL cp_para_env_retain(preconditioner_env%para_env)
108      CALL cp_blacs_env_retain(preconditioner_env%ctxt)
109
110   END SUBROUTINE init_preconditioner
111
112! **************************************************************************************************
113!> \brief ...
114!> \param preconditioner_env ...
115! **************************************************************************************************
116   SUBROUTINE destroy_preconditioner(preconditioner_env)
117
118      TYPE(preconditioner_type)                          :: preconditioner_env
119
120      CHARACTER(len=*), PARAMETER :: routineN = 'destroy_preconditioner', &
121         routineP = moduleN//':'//routineN
122
123      INTEGER                                            :: handle, i
124
125      CALL timeset(routineN, handle)
126
127      IF (ASSOCIATED(preconditioner_env%sparse_matrix)) THEN
128         CALL dbcsr_deallocate_matrix(preconditioner_env%sparse_matrix)
129         NULLIFY (preconditioner_env%sparse_matrix)
130      ENDIF
131
132      IF (ASSOCIATED(preconditioner_env%fm)) THEN
133         CALL cp_fm_release(preconditioner_env%fm)
134      ENDIF
135      IF (ASSOCIATED(preconditioner_env%dbcsr_matrix)) THEN
136         CALL dbcsr_release_p(preconditioner_env%dbcsr_matrix)
137      ENDIF
138      IF (ASSOCIATED(preconditioner_env%max_ev_vector)) THEN
139         CALL dbcsr_release_p(preconditioner_env%max_ev_vector)
140      ENDIF
141      IF (ASSOCIATED(preconditioner_env%min_ev_vector)) THEN
142         CALL dbcsr_release_p(preconditioner_env%min_ev_vector)
143      ENDIF
144      IF (ASSOCIATED(preconditioner_env%occ_evals)) THEN
145         DEALLOCATE (preconditioner_env%occ_evals)
146      ENDIF
147      IF (ASSOCIATED(preconditioner_env%full_evals)) THEN
148         DEALLOCATE (preconditioner_env%full_evals)
149      ENDIF
150      IF (ASSOCIATED(preconditioner_env%inverse_history)) THEN
151         DO i = 1, SIZE(preconditioner_env%inverse_history)
152            CALL dbcsr_release_p(preconditioner_env%inverse_history(i)%matrix)
153         END DO
154         DEALLOCATE (preconditioner_env%inverse_history)
155      ENDIF
156      CALL cp_para_env_release(preconditioner_env%para_env)
157      CALL cp_blacs_env_release(preconditioner_env%ctxt)
158
159      preconditioner_env%in_use = 0
160      preconditioner_env%cholesky_use = cholesky_reduce
161
162      CALL timestop(handle)
163
164   END SUBROUTINE destroy_preconditioner
165
166END MODULE preconditioner_types
167
168