1!--------------------------------------------------------------------------------------------------!
2!   CP2K: A general program to perform molecular dynamics simulations                              !
3!   Copyright (C) 2000 - 2019  CP2K developers group                                               !
4!--------------------------------------------------------------------------------------------------!
5
6! **************************************************************************************************
7!> \brief module that contains the definitions of the scf types
8!> \par History
9!>      02.2003 created [fawzi]
10!> \author fawzi
11! **************************************************************************************************
12MODULE qs_scf_types
13   USE cp_dbcsr_operations,             ONLY: dbcsr_deallocate_matrix_set
14   USE cp_fm_types,                     ONLY: cp_fm_p_type,&
15                                              cp_fm_release,&
16                                              cp_fm_type
17   USE cp_fm_vect,                      ONLY: cp_fm_vect_dealloc
18   USE dbcsr_api,                       ONLY: dbcsr_deallocate_matrix,&
19                                              dbcsr_p_type,&
20                                              dbcsr_type
21   USE input_section_types,             ONLY: section_vals_get_subs_vals,&
22                                              section_vals_type,&
23                                              section_vals_val_get
24   USE kinds,                           ONLY: dp
25   USE outer_scf_control_types,         ONLY: qs_outer_scf_type
26   USE preconditioner_types,            ONLY: destroy_preconditioner,&
27                                              preconditioner_p_type
28   USE qs_block_davidson_types,         ONLY: block_davidson_release,&
29                                              davidson_type
30   USE qs_density_mixing_types,         ONLY: direct_mixing_nr,&
31                                              mixing_storage_create,&
32                                              mixing_storage_release,&
33                                              mixing_storage_type
34   USE qs_diis_types,                   ONLY: qs_diis_b_release,&
35                                              qs_diis_buffer_type
36   USE qs_fb_env_types,                 ONLY: fb_env_has_data,&
37                                              fb_env_nullify,&
38                                              fb_env_obj,&
39                                              fb_env_release
40   USE qs_ot_types,                     ONLY: qs_ot_destroy,&
41                                              qs_ot_type
42#include "./base/base_uses.f90"
43
44   IMPLICIT NONE
45   PRIVATE
46
47   LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .TRUE.
48
49   CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_scf_types'
50
51   INTEGER, PARAMETER, PUBLIC :: general_diag_method_nr = 1, &
52                                 special_diag_method_nr = 2, &
53                                 ot_diag_method_nr = 3, &
54                                 block_krylov_diag_method_nr = 4, &
55                                 block_davidson_diag_method_nr = 5, &
56                                 ot_method_nr = 10, &
57                                 filter_matrix_diag_method_nr = 20
58
59   INTEGER, SAVE, PRIVATE :: last_scf_env_id = 0
60
61   PUBLIC :: qs_scf_env_type
62   PUBLIC :: scf_env_retain, scf_env_release, scf_env_create, scf_env_did_change
63   PUBLIC :: krylov_space_type, krylov_space_create, subspace_env_type
64   PUBLIC :: diag_subspace_env_create
65
66! **************************************************************************************************
67!> \brief wrapper for temporary and cached objects used in the scf iteration
68!> \par History
69!>      02.2003 created [fawzi]
70!> \author fawzi
71! **************************************************************************************************
72   TYPE krylov_space_type
73      INTEGER :: nkrylov, nblock, nmo_conv, nmo_nc, max_iter
74      LOGICAL :: always_check_conv
75      REAL(dp) :: eps_std_diag, eps_conv, eps_adapt, max_res_norm, min_res_norm
76      REAL(dp), DIMENSION(:), POINTER :: c_eval, t_eval
77      TYPE(cp_fm_p_type), DIMENSION(:), POINTER :: v_mat, mo_conv, mo_refine
78      TYPE(cp_fm_type), POINTER ::  tmp_mat
79      !NOTE: the following matrices are small and could be used as standard array rather than distributed fm
80      TYPE(cp_fm_type), POINTER :: block1_mat, block2_mat, block3_mat, block4_mat, block5_mat
81      TYPE(cp_fm_p_type), DIMENSION(:), POINTER ::  c_vec, chc_mat
82   END TYPE krylov_space_type
83
84   TYPE subspace_env_type
85      INTEGER :: max_iter, mixing_method
86      REAL(dp) :: eps_diag_sub, eps_ene, eps_adapt
87      TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: p_matrix_store
88      TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: p_matrix_mix
89      TYPE(cp_fm_p_type), DIMENSION(:), POINTER :: chc_mat, c_vec, c0
90      TYPE(mixing_storage_type), POINTER :: mixing_store
91   END TYPE subspace_env_type
92
93   TYPE floating_basis_type
94      REAL(KIND=dp), DIMENSION(:, :), POINTER :: gradient
95   END TYPE floating_basis_type
96   ! **************************************************************************************************
97   TYPE qs_scf_env_type
98      TYPE(qs_outer_scf_type) :: outer_scf
99      INTEGER :: ref_count, id_nr, print_count, iter_count
100      INTEGER :: cholesky_method, nelectron, method, mixing_method, nskip_mixing
101      REAL(KIND=dp) :: iter_param, iter_delta, p_mix_alpha
102      CHARACTER(len=15) :: iter_method
103      COMPLEX(KIND=dp), DIMENSION(:, :, :), POINTER :: cc_buffer
104      LOGICAL :: print_iter_line, skip_mixing, skip_diis, needs_ortho
105      TYPE(mixing_storage_type), POINTER :: mixing_store
106      TYPE(cp_fm_p_type), DIMENSION(:), POINTER :: scf_work1
107      TYPE(cp_fm_type), POINTER  :: scf_work2, ortho, ortho_m1, s_half, s_minus_one
108      TYPE(krylov_space_type), POINTER :: krylov_space
109      TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: p_delta, p_mix_new
110      TYPE(dbcsr_type), POINTER :: ortho_dbcsr, buf1_dbcsr, buf2_dbcsr
111      TYPE(preconditioner_p_type), DIMENSION(:), POINTER :: ot_preconditioner
112      TYPE(qs_ot_type), POINTER, DIMENSION(:)  :: qs_ot_env
113      TYPE(qs_diis_buffer_type), POINTER :: scf_diis_buffer
114      TYPE(subspace_env_type), POINTER :: subspace_env
115      TYPE(davidson_type), POINTER, DIMENSION(:) :: block_davidson_env
116      TYPE(fb_env_obj) :: filter_matrix_env
117      TYPE(floating_basis_type) :: floating_basis
118      !> reference molecular orbitals for the maximum overlap method
119      TYPE(cp_fm_p_type), DIMENSION(:), POINTER          :: mom_ref_mo_coeff
120      !> MOM-related work matrices
121      TYPE(cp_fm_p_type), DIMENSION(:), POINTER          :: mom_overlap, mom_s_mo_coeff
122   END TYPE qs_scf_env_type
123
124CONTAINS
125
126! **************************************************************************************************
127!> \brief allocates and initialize an scf_env
128!> \param scf_env the scf env to initialize
129!> \par History
130!>      02.2003 created [fawzi]
131!> \author fawzi
132! **************************************************************************************************
133   SUBROUTINE scf_env_create(scf_env)
134      TYPE(qs_scf_env_type), POINTER                     :: scf_env
135
136      CHARACTER(len=*), PARAMETER :: routineN = 'scf_env_create', routineP = moduleN//':'//routineN
137
138      INTEGER                                            :: handle
139
140      CALL timeset(routineN, handle)
141
142      ALLOCATE (scf_env)
143      scf_env%ref_count = 1
144      scf_env%print_count = 0
145      last_scf_env_id = last_scf_env_id + 1
146      scf_env%id_nr = last_scf_env_id
147      scf_env%print_count = 0
148      scf_env%iter_count = 0
149      scf_env%nelectron = 0
150      scf_env%iter_param = 0.0_dp
151      scf_env%iter_delta = 0.0_dp
152      scf_env%iter_method = ""
153      scf_env%print_iter_line = .TRUE.
154      scf_env%skip_mixing = .FALSE.
155      scf_env%skip_diis = .FALSE.
156      scf_env%needs_ortho = .FALSE.
157      scf_env%method = -1
158      scf_env%mixing_method = -1
159      scf_env%p_mix_alpha = 1.0_dp
160      scf_env%cholesky_method = -1
161      scf_env%outer_scf%iter_count = 0
162      NULLIFY (scf_env%outer_scf%variables)
163      NULLIFY (scf_env%outer_scf%gradient)
164      NULLIFY (scf_env%outer_scf%energy)
165      NULLIFY (scf_env%outer_scf%count)
166      NULLIFY (scf_env%outer_scf%inv_jacobian)
167      scf_env%outer_scf%deallocate_jacobian = .TRUE.
168      NULLIFY (scf_env%scf_work1)
169      NULLIFY (scf_env%scf_work2)
170      NULLIFY (scf_env%ortho)
171      NULLIFY (scf_env%ortho_dbcsr)
172      NULLIFY (scf_env%ortho_m1)
173      NULLIFY (scf_env%p_mix_new)
174      NULLIFY (scf_env%ot_preconditioner)
175      NULLIFY (scf_env%qs_ot_env)
176      NULLIFY (scf_env%scf_diis_buffer)
177      NULLIFY (scf_env%buf1_dbcsr)
178      NULLIFY (scf_env%buf2_dbcsr)
179      NULLIFY (scf_env%s_half)
180      NULLIFY (scf_env%p_delta)
181      NULLIFY (scf_env%s_minus_one)
182      NULLIFY (scf_env%cc_buffer)
183      NULLIFY (scf_env%mixing_store)
184      NULLIFY (scf_env%krylov_space)
185      NULLIFY (scf_env%subspace_env)
186      NULLIFY (scf_env%block_davidson_env)
187      NULLIFY (scf_env%floating_basis%gradient)
188      CALL fb_env_nullify(scf_env%filter_matrix_env)
189      NULLIFY (scf_env%mom_ref_mo_coeff)
190      NULLIFY (scf_env%mom_overlap)
191      NULLIFY (scf_env%mom_s_mo_coeff)
192
193      CALL timestop(handle)
194
195   END SUBROUTINE scf_env_create
196
197! **************************************************************************************************
198!> \brief retains an scf_env (see doc/ReferenceCounting.html)
199!> \param scf_env the environment to retain
200!> \par History
201!>      02.2003 created [fawzi]
202!> \author fawzi
203! **************************************************************************************************
204   SUBROUTINE scf_env_retain(scf_env)
205
206      TYPE(qs_scf_env_type), POINTER                     :: scf_env
207
208      CHARACTER(len=*), PARAMETER :: routineN = 'scf_env_retain', routineP = moduleN//':'//routineN
209
210      INTEGER                                            :: handle
211
212      CALL timeset(routineN, handle)
213
214      CPASSERT(ASSOCIATED(scf_env))
215      CPASSERT(scf_env%ref_count > 0)
216      scf_env%ref_count = scf_env%ref_count + 1
217
218      CALL timestop(handle)
219
220   END SUBROUTINE scf_env_retain
221
222! **************************************************************************************************
223!> \brief function to be called to inform the scf_env about changes
224!> \param scf_env the scf env to inform
225!> \par History
226!>      03.2003 created [fawzi]
227!> \author fawzi
228! **************************************************************************************************
229   SUBROUTINE scf_env_did_change(scf_env)
230      TYPE(qs_scf_env_type), POINTER                     :: scf_env
231
232      CHARACTER(len=*), PARAMETER :: routineN = 'scf_env_did_change', &
233         routineP = moduleN//':'//routineN
234
235      INTEGER                                            :: handle, i
236
237      CALL timeset(routineN, handle)
238
239      CPASSERT(ASSOCIATED(scf_env))
240      CPASSERT(scf_env%ref_count > 0)
241
242      IF (ASSOCIATED(scf_env%p_mix_new)) THEN
243         CALL dbcsr_deallocate_matrix_set(scf_env%p_mix_new)
244      END IF
245      IF (ASSOCIATED(scf_env%p_delta)) THEN
246         CALL dbcsr_deallocate_matrix_set(scf_env%p_delta)
247      END IF
248      IF (ASSOCIATED(scf_env%mom_ref_mo_coeff)) THEN
249         DO i = 1, SIZE(scf_env%mom_ref_mo_coeff)
250            CALL cp_fm_release(scf_env%mom_ref_mo_coeff(i)%matrix)
251         END DO
252         DEALLOCATE (scf_env%mom_ref_mo_coeff)
253      END IF
254
255      CALL timestop(handle)
256
257   END SUBROUTINE scf_env_did_change
258
259! **************************************************************************************************
260!> \brief releases an scf_env (see doc/ReferenceCounting.html)
261!> \param scf_env the environment to release
262!> \par History
263!>      02.2003 created [fawzi]
264!> \author fawzi
265! **************************************************************************************************
266   SUBROUTINE scf_env_release(scf_env)
267
268      TYPE(qs_scf_env_type), POINTER                     :: scf_env
269
270      CHARACTER(len=*), PARAMETER :: routineN = 'scf_env_release', &
271         routineP = moduleN//':'//routineN
272
273      INTEGER                                            :: handle, i
274
275      CALL timeset(routineN, handle)
276
277      IF (ASSOCIATED(scf_env)) THEN
278         CPASSERT(scf_env%ref_count > 0)
279         scf_env%ref_count = scf_env%ref_count - 1
280         IF (scf_env%ref_count < 1) THEN
281            CALL cp_fm_vect_dealloc(scf_env%scf_work1)
282            CALL cp_fm_release(scf_env%scf_work2)
283            CALL cp_fm_release(scf_env%ortho)
284            CALL cp_fm_release(scf_env%ortho_m1)
285            IF (ASSOCIATED(scf_env%ortho_dbcsr)) THEN
286               ! we should not end up here, and give back using the pools
287               CPASSERT(.TRUE.)
288               CALL dbcsr_deallocate_matrix(scf_env%ortho_dbcsr)
289            END IF
290            IF (ASSOCIATED(scf_env%buf1_dbcsr)) THEN
291               ! we should not end up here, and give back using the pools
292               CPASSERT(.TRUE.)
293               CALL dbcsr_deallocate_matrix(scf_env%buf1_dbcsr)
294            END IF
295            IF (ASSOCIATED(scf_env%buf2_dbcsr)) THEN
296               ! we should not end up here, and give back using the pools
297               CPASSERT(.TRUE.)
298               CALL dbcsr_deallocate_matrix(scf_env%buf2_dbcsr)
299            END IF
300            CALL cp_fm_release(scf_env%s_half)
301            CALL cp_fm_release(scf_env%s_minus_one)
302            IF (ASSOCIATED(scf_env%p_mix_new)) THEN
303               ! we should not end up here, and give back using the pools
304               CPASSERT(.TRUE.)
305               CALL dbcsr_deallocate_matrix_set(scf_env%p_mix_new)
306            END IF
307            IF (ASSOCIATED(scf_env%p_delta)) THEN
308               ! we should not end up here, and give back using the pools
309               CPASSERT(.TRUE.)
310               CALL dbcsr_deallocate_matrix_set(scf_env%p_delta)
311            END IF
312            IF (ASSOCIATED(scf_env%ot_preconditioner)) THEN
313               DO i = 1, SIZE(scf_env%ot_preconditioner)
314                  CALL destroy_preconditioner(scf_env%ot_preconditioner(i)%preconditioner)
315                  DEALLOCATE (scf_env%ot_preconditioner(i)%preconditioner)
316               END DO
317               DEALLOCATE (scf_env%ot_preconditioner)
318            END IF
319            IF (ASSOCIATED(scf_env%qs_ot_env)) THEN
320               DO i = 1, SIZE(scf_env%qs_ot_env)
321                  CALL qs_ot_destroy(scf_env%qs_ot_env(i))
322               END DO
323               DEALLOCATE (scf_env%qs_ot_env)
324            END IF
325            CALL qs_diis_b_release(scf_env%scf_diis_buffer)
326            IF (ASSOCIATED(scf_env%outer_scf%variables)) THEN
327               DEALLOCATE (scf_env%outer_scf%variables)
328            END IF
329            IF (ASSOCIATED(scf_env%outer_scf%count)) THEN
330               DEALLOCATE (scf_env%outer_scf%count)
331            END IF
332            IF (ASSOCIATED(scf_env%outer_scf%gradient)) THEN
333               DEALLOCATE (scf_env%outer_scf%gradient)
334            END IF
335            IF (ASSOCIATED(scf_env%outer_scf%inv_jacobian)) THEN
336               DEALLOCATE (scf_env%outer_scf%inv_jacobian)
337            END IF
338            IF (ASSOCIATED(scf_env%outer_scf%energy)) THEN
339               DEALLOCATE (scf_env%outer_scf%energy)
340            END IF
341            IF (ASSOCIATED(scf_env%cc_buffer)) THEN
342               DEALLOCATE (scf_env%cc_buffer)
343            END IF
344            IF (ASSOCIATED(scf_env%mixing_store)) THEN
345               CALL mixing_storage_release(scf_env%mixing_store)
346            END IF
347            IF (ASSOCIATED(scf_env%krylov_space)) THEN
348               CALL krylov_space_release(scf_env%krylov_space)
349            END IF
350            IF (ASSOCIATED(scf_env%subspace_env)) THEN
351               CALL diag_subspace_env_release(scf_env%subspace_env)
352            END IF
353            IF (ASSOCIATED(scf_env%block_davidson_env)) THEN
354               CALL block_davidson_release(scf_env%block_davidson_env)
355            END IF
356            IF (fb_env_has_data(scf_env%filter_matrix_env)) THEN
357               CALL fb_env_release(scf_env%filter_matrix_env)
358            END IF
359            IF (ASSOCIATED(scf_env%floating_basis%gradient)) THEN
360               DEALLOCATE (scf_env%floating_basis%gradient)
361            END IF
362            IF (ASSOCIATED(scf_env%mom_ref_mo_coeff)) THEN
363               DO i = 1, SIZE(scf_env%mom_ref_mo_coeff)
364                  CALL cp_fm_release(scf_env%mom_ref_mo_coeff(i)%matrix)
365               END DO
366               DEALLOCATE (scf_env%mom_ref_mo_coeff)
367            END IF
368            IF (ASSOCIATED(scf_env%mom_overlap)) THEN
369               DO i = 1, SIZE(scf_env%mom_overlap)
370                  CALL cp_fm_release(scf_env%mom_overlap(i)%matrix)
371               END DO
372               DEALLOCATE (scf_env%mom_overlap)
373            END IF
374            IF (ASSOCIATED(scf_env%mom_s_mo_coeff)) THEN
375               DO i = 1, SIZE(scf_env%mom_s_mo_coeff)
376                  CALL cp_fm_release(scf_env%mom_s_mo_coeff(i)%matrix)
377               END DO
378               DEALLOCATE (scf_env%mom_s_mo_coeff)
379            END IF
380            DEALLOCATE (scf_env)
381         END IF
382      END IF
383
384      NULLIFY (scf_env)
385
386      CALL timestop(handle)
387
388   END SUBROUTINE scf_env_release
389
390! **************************************************************************************************
391!> \brief  creates krylov space
392!> \param krylov_space ...
393!> \param scf_section ...
394!> \par History
395!>      05.2009 created [MI]
396!> \author [MI]
397! **************************************************************************************************
398   SUBROUTINE krylov_space_create(krylov_space, scf_section)
399
400      TYPE(krylov_space_type), POINTER                   :: krylov_space
401      TYPE(section_vals_type), POINTER                   :: scf_section
402
403      CHARACTER(len=*), PARAMETER :: routineN = 'krylov_space_create', &
404         routineP = moduleN//':'//routineN
405
406      CPASSERT(.NOT. ASSOCIATED(krylov_space))
407      ALLOCATE (krylov_space)
408
409      NULLIFY (krylov_space%c_eval, krylov_space%t_eval)
410      NULLIFY (krylov_space%v_mat)
411      NULLIFY (krylov_space%mo_conv, krylov_space%mo_refine)
412      NULLIFY (krylov_space%chc_mat, krylov_space%c_vec)
413      NULLIFY (krylov_space%tmp_mat)
414      NULLIFY (krylov_space%block1_mat, krylov_space%block2_mat)
415      NULLIFY (krylov_space%block3_mat, krylov_space%block4_mat, krylov_space%block5_mat)
416
417      CALL section_vals_val_get(scf_section, "DIAGONALIZATION%MAX_ITER", &
418                                i_val=krylov_space%max_iter)
419      CALL section_vals_val_get(scf_section, "DIAGONALIZATION%KRYLOV%NKRYLOV", &
420                                i_val=krylov_space%nkrylov)
421      CALL section_vals_val_get(scf_section, "DIAGONALIZATION%KRYLOV%NBLOCK", &
422                                i_val=krylov_space%nblock)
423      CALL section_vals_val_get(scf_section, "DIAGONALIZATION%KRYLOV%EPS_KRYLOV", &
424                                r_val=krylov_space%eps_conv)
425      CALL section_vals_val_get(scf_section, "DIAGONALIZATION%KRYLOV%EPS_STD_DIAG", &
426                                r_val=krylov_space%eps_std_diag)
427      CALL section_vals_val_get(scf_section, "DIAGONALIZATION%EPS_ADAPT", &
428                                r_val=krylov_space%eps_adapt)
429      CALL section_vals_val_get(scf_section, "DIAGONALIZATION%KRYLOV%CHECK_MOS_CONV", &
430                                l_val=krylov_space%always_check_conv)
431
432   END SUBROUTINE krylov_space_create
433
434! **************************************************************************************************
435!> \brief releases krylov space
436!> \param krylov_space ...
437!> \par History
438!>      05.2009 created [MI]
439!> \author [MI]
440! **************************************************************************************************
441   SUBROUTINE krylov_space_release(krylov_space)
442      TYPE(krylov_space_type), POINTER                   :: krylov_space
443
444      CHARACTER(len=*), PARAMETER :: routineN = 'krylov_space_release', &
445         routineP = moduleN//':'//routineN
446
447      INTEGER                                            :: i
448
449      IF (ASSOCIATED(krylov_space)) THEN
450
451         DEALLOCATE (krylov_space%c_eval)
452         DEALLOCATE (krylov_space%t_eval)
453
454         DO i = 1, SIZE(krylov_space%v_mat)
455            CALL cp_fm_release(krylov_space%v_mat(i)%matrix)
456         END DO
457         DEALLOCATE (krylov_space%v_mat)
458
459         DO i = 1, SIZE(krylov_space%mo_conv)
460            CALL cp_fm_release(krylov_space%mo_conv(i)%matrix)
461         END DO
462         DEALLOCATE (krylov_space%mo_conv)
463
464         DO i = 1, SIZE(krylov_space%mo_refine)
465            CALL cp_fm_release(krylov_space%mo_refine(i)%matrix)
466         END DO
467         DEALLOCATE (krylov_space%mo_refine)
468
469         DO i = 1, SIZE(krylov_space%chc_mat)
470            CALL cp_fm_release(krylov_space%chc_mat(i)%matrix)
471         END DO
472         DEALLOCATE (krylov_space%chc_mat)
473         DO i = 1, SIZE(krylov_space%c_vec)
474            CALL cp_fm_release(krylov_space%c_vec(i)%matrix)
475         END DO
476         DEALLOCATE (krylov_space%c_vec)
477         CALL cp_fm_release(krylov_space%tmp_mat)
478         CALL cp_fm_release(krylov_space%block1_mat)
479         CALL cp_fm_release(krylov_space%block2_mat)
480         CALL cp_fm_release(krylov_space%block3_mat)
481         CALL cp_fm_release(krylov_space%block4_mat)
482         CALL cp_fm_release(krylov_space%block5_mat)
483
484         DEALLOCATE (krylov_space)
485
486         NULLIFY (krylov_space)
487      END IF
488
489   END SUBROUTINE krylov_space_release
490
491! **************************************************************************************************
492!> \brief creates subspace-rotation environment
493!> \param subspace_env ...
494!> \param scf_section ...
495!> \param ecut ...
496!> \par History
497!>      09.2009 created [MI]
498!> \author [MI]
499! **************************************************************************************************
500   SUBROUTINE diag_subspace_env_create(subspace_env, scf_section, ecut)
501
502      TYPE(subspace_env_type), POINTER                   :: subspace_env
503      TYPE(section_vals_type), POINTER                   :: scf_section
504      REAL(dp), INTENT(IN)                               :: ecut
505
506      CHARACTER(len=*), PARAMETER :: routineN = 'diag_subspace_env_create', &
507         routineP = moduleN//':'//routineN
508
509      LOGICAL                                            :: do_mixing
510      TYPE(section_vals_type), POINTER                   :: mixing_section
511
512      CPASSERT(.NOT. ASSOCIATED(subspace_env))
513      ALLOCATE (subspace_env)
514
515      NULLIFY (subspace_env%p_matrix_store)
516      NULLIFY (subspace_env%p_matrix_mix)
517      NULLIFY (subspace_env%chc_mat)
518      NULLIFY (subspace_env%c_vec)
519      NULLIFY (subspace_env%c0)
520      NULLIFY (subspace_env%mixing_store)
521      NULLIFY (mixing_section)
522
523      CALL section_vals_val_get(scf_section, "DIAGONALIZATION%DIAG_SUB_SCF%MAX_ITER", &
524                                i_val=subspace_env%max_iter)
525      CALL section_vals_val_get(scf_section, "DIAGONALIZATION%DIAG_SUB_SCF%EPS_ENE", &
526                                r_val=subspace_env%eps_ene)
527      CALL section_vals_val_get(scf_section, "DIAGONALIZATION%DIAG_SUB_SCF%EPS_SKIP_SUB_DIAG", &
528                                r_val=subspace_env%eps_diag_sub)
529      CALL section_vals_val_get(scf_section, "DIAGONALIZATION%DIAG_SUB_SCF%EPS_ADAPT_SCF", &
530                                r_val=subspace_env%eps_adapt)
531      subspace_env%mixing_method = 0
532      do_mixing = .FALSE.
533      mixing_section => section_vals_get_subs_vals(scf_section, "DIAGONALIZATION%DIAG_SUB_SCF%MIXING")
534      CALL section_vals_val_get(mixing_section, "_SECTION_PARAMETERS_", &
535                                l_val=do_mixing)
536      IF (do_mixing) THEN
537         CALL section_vals_val_get(mixing_section, "METHOD", &
538                                   i_val=subspace_env%mixing_method)
539         IF (subspace_env%mixing_method >= direct_mixing_nr) &
540            CALL mixing_storage_create(subspace_env%mixing_store, mixing_section, &
541                                       subspace_env%mixing_method, ecut=ecut)
542      END IF
543
544   END SUBROUTINE diag_subspace_env_create
545
546! **************************************************************************************************
547!> \brief releases subspace-rotation environment
548!> \param subspace_env ...
549!> \par History
550!>      09.2009 created [MI]
551!> \author [MI]
552! **************************************************************************************************
553   SUBROUTINE diag_subspace_env_release(subspace_env)
554      TYPE(subspace_env_type), POINTER                   :: subspace_env
555
556      CHARACTER(len=*), PARAMETER :: routineN = 'diag_subspace_env_release', &
557         routineP = moduleN//':'//routineN
558
559      INTEGER                                            :: i
560
561      IF (ASSOCIATED(subspace_env)) THEN
562
563         IF (ASSOCIATED(subspace_env%p_matrix_store)) THEN
564
565            CPASSERT(.TRUE.)
566            CALL dbcsr_deallocate_matrix_set(subspace_env%p_matrix_store)
567         ENDIF
568         DO i = 1, SIZE(subspace_env%chc_mat)
569            CALL cp_fm_release(subspace_env%chc_mat(i)%matrix)
570         END DO
571         DEALLOCATE (subspace_env%chc_mat)
572         DO i = 1, SIZE(subspace_env%c_vec)
573            CALL cp_fm_release(subspace_env%c_vec(i)%matrix)
574         END DO
575         DEALLOCATE (subspace_env%c_vec)
576         DO i = 1, SIZE(subspace_env%c0)
577            CALL cp_fm_release(subspace_env%c0(i)%matrix)
578         END DO
579         DEALLOCATE (subspace_env%c0)
580
581         IF (ASSOCIATED(subspace_env%mixing_store)) THEN
582            CALL mixing_storage_release(subspace_env%mixing_store)
583         END IF
584
585         DEALLOCATE (subspace_env)
586      END IF
587
588   END SUBROUTINE diag_subspace_env_release
589
590END MODULE qs_scf_types
591