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 for all ALMO-based methods
8!> \par History
9!>       2011.05 created [Rustam Z Khaliullin]
10!>       2018.09 smearing support [Ruben Staub]
11!> \author Rustam Z Khaliullin
12! **************************************************************************************************
13MODULE almo_scf_types
14   USE cp_blacs_env,                    ONLY: cp_blacs_env_type
15   USE cp_para_types,                   ONLY: cp_para_env_type
16   USE dbcsr_api,                       ONLY: dbcsr_release,&
17                                              dbcsr_type
18   USE domain_submatrix_types,          ONLY: domain_map_type,&
19                                              domain_submatrix_type
20   USE input_constants,                 ONLY: &
21        cg_dai_yuan, cg_fletcher, cg_fletcher_reeves, cg_hager_zhang, cg_hestenes_stiefel, &
22        cg_liu_storey, cg_polak_ribiere, cg_zero, optimizer_diis, optimizer_pcg, &
23        xalmo_prec_domain, xalmo_prec_full, xalmo_prec_zero
24   USE kinds,                           ONLY: dp
25#include "./base/base_uses.f90"
26
27   IMPLICIT NONE
28
29   PRIVATE
30
31   CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'almo_scf_types'
32
33   INTEGER, PARAMETER, PUBLIC   :: almo_mat_dim_aobasis = 1, &
34                                   almo_mat_dim_occ = 2, &
35                                   almo_mat_dim_virt = 3, &
36                                   almo_mat_dim_virt_full = 4, &
37                                   almo_mat_dim_domains = 5, &
38                                   almo_mat_dim_virt_disc = 6
39   REAL(KIND=dp), PARAMETER, PUBLIC :: almo_max_cutoff_multiplier = 2.2_dp
40
41   PUBLIC :: almo_scf_env_type, optimizer_options_type, &
42             print_optimizer_options, almo_scf_env_release, &
43             almo_scf_history_type
44
45   ! methods that add penalty terms to the energy functional
46   TYPE penalty_type
47
48      REAL(KIND=dp)      :: occ_vol_coeff
49      INTEGER            :: occ_vol_method
50
51   END TYPE penalty_type
52
53   ! almo-based electronic structure analysis
54   TYPE almo_analysis_type
55
56      ! switch analysis on/off
57      LOGICAL :: do_analysis
58
59      INTEGER :: frozen_mo_energy_term
60
61   END TYPE almo_analysis_type
62
63   TYPE optimizer_options_type
64
65      ! SCF procedure for the block-diagonal ALMOs
66      !REAL(KIND=dp)         :: eps_scf_bd -> eps_error
67      !INTEGER               :: max_scf_bd -> max_iter
68      !INTEGER               :: ndiis_bd -> ndiis
69
70      ! SCF procedure for the quenched ALMOs (xALMOs)
71      !REAL(KIND=dp)         :: eps_scf_q -> eps_error
72      !REAL(KIND=dp)         :: eps_lin_search ->  eps_lin_search_error
73      !INTEGER               :: max_scf_q -> max_iter
74      !INTEGER               :: scf_conjugator -> conjugator
75      !INTEGER               :: outer_max_scf_q -> max_iter for a separate optimizer
76      !INTEGER               :: ndiis_q -> ndiis
77
78      REAL(KIND=dp)  :: eps_error, &
79                        eps_error_early, &
80                        lin_search_eps_error, &
81                        lin_search_step_size_guess, &
82                        neglect_threshold
83
84      INTEGER        :: optimizer_type ! diis, pcg, etc.
85
86      INTEGER        :: preconditioner, & ! preconditioner type
87                        conjugator, & ! conjugator type
88                        max_iter, &
89                        max_iter_early, &
90                        max_iter_outer_loop, &
91                        ndiis ! diis history length
92
93      LOGICAL        :: early_stopping_on = .FALSE.
94
95   END TYPE optimizer_options_type
96
97   TYPE almo_scf_history_type
98      INTEGER :: istore, nstore
99      TYPE(dbcsr_type), DIMENSION(:, :), ALLOCATABLE :: matrix_p_up_down
100      !TYPE(dbcsr_type), DIMENSION(:, :), ALLOCATABLE :: matrix_x
101      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE :: matrix_t
102   END TYPE
103
104   ! the structure contains general info about the system
105   TYPE almo_scf_env_type
106
107      TYPE(cp_para_env_type), POINTER  :: para_env
108      TYPE(cp_blacs_env_type), POINTER  :: blacs_env
109
110      INTEGER :: nspins, nelectrons_total, naos
111      INTEGER :: natoms, nmolecules
112      INTEGER, DIMENSION(2) :: nelectrons_spin
113
114      ! Definitions:
115      ! I.  Domain - a subset of basis functions (e.g. AOs),
116      ! II. Group  - a subset of electrons delocalized within a domain.
117      !
118      ! The following variables specify the group-domain structure
119      ! of the system. Several rules must be obeyed:
120      ! 1. There should be no zero domains (i.e. domain contains at least one AO).
121      ! 2. There should be no empty domains (i.e. all domains must be populated
122      !     by at least one electron).
123      ! 3. If two groups are localized within the same domain they are combined
124      ! It follows that the number of domains is equal to the number of groups
125      !
126      ! Number of domains
127      INTEGER :: ndomains
128
129      ! List of atoms, whose basis functions are included into the domain.
130      ! It is assumed that:
131      !   (a) basis functions are localized and atom-labeled,
132      !   (b) basis functions are grouped into atomic sets (i.e. if a basis
133      !       function on an atom is in domain A then all basis functions on
134      !       this atom are in domain A)
135      !TYPE(domain_list_type), DIMENSION(:), ALLOCATABLE   :: atom_list_of_domain
136      ! List of basis functions included into the domain
137      !TYPE(domain_list_type), DIMENSION(:), ALLOCATABLE   :: basis_list_of_domain
138
139      ! Number of electrons of each spin for a given domain (second dim is spin).
140      ! Note that some domains can be populated only with alpha or beta electrons.
141      INTEGER, DIMENSION(:, :), ALLOCATABLE                :: nocc_of_domain
142      ! Number of basis functions for a given domain
143      INTEGER, DIMENSION(:), ALLOCATABLE                  :: nbasis_of_domain
144      ! Define number of virtuals for a given domain: nvirt = nbasis - nocc
145      INTEGER, DIMENSION(:, :), ALLOCATABLE                :: nvirt_full_of_domain
146      ! Define the dimension of truncated virtual subspace for a given domain:
147      INTEGER, DIMENSION(:, :), ALLOCATABLE                :: nvirt_of_domain
148      ! Define the dimension of discarded virtual subspace for a given domain:
149      INTEGER, DIMENSION(:, :), ALLOCATABLE                :: nvirt_disc_of_domain
150      ! Each domain has its own mu - "fermi" level
151      REAL(KIND=dp), DIMENSION(:, :), ALLOCATABLE          :: mu_of_domain
152      INTEGER, DIMENSION(:), ALLOCATABLE                  :: first_atom_of_domain
153      INTEGER, DIMENSION(:), ALLOCATABLE                  :: last_atom_of_domain
154      ! The following arrays are useful only with non-overlapping domains
155      ! RZK-warning generalization is required
156      INTEGER, DIMENSION(:), ALLOCATABLE        :: domain_index_of_ao
157      INTEGER, DIMENSION(:), ALLOCATABLE        :: domain_index_of_atom
158
159      ! Charge of domains
160      INTEGER, DIMENSION(:), ALLOCATABLE                  :: charge_of_domain
161      ! Charge of domains
162      INTEGER, DIMENSION(:), ALLOCATABLE                  :: multiplicity_of_domain
163
164      ! The matrix contains information about the delocalization of
165      ! alpha and beta electrons.
166      ! Rows denote basis function, columns denote electrons.
167      ! Non-zero (j,i) entry means that electron j can delocalize over
168      ! basis function i. 0.0 means no delocalization
169      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE   :: quench_t
170      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE   :: quench_t_blk
171      ! Local array for a compact description of quench_t
172      TYPE(domain_map_type), DIMENSION(:), ALLOCATABLE :: domain_map
173
174      ! Several special cases for the structure of the group-domain matrix:
175      ! 1. The basis functions can be grouped into:
176      !    a. molecular sets
177      !    b. atomic sets
178      ! 2. Electrons can be grouped into:
179      !    a. molecular sets
180      !    b. atomic sets
181      INTEGER :: domain_layout_mos, domain_layout_aos
182      ! ALMO  constraint type.
183      INTEGER :: constraint_type
184
185      ! Desciptors of molecules
186      !INTEGER, DIMENSION(:), ALLOCATABLE        :: molecule_index_of_atom
187      !INTEGER, DIMENSION(:), ALLOCATABLE        :: first_atom_of_molecule
188      !INTEGER, DIMENSION(:), ALLOCATABLE        :: nbasis_of_molecule
189      !INTEGER, DIMENSION(:,:), ALLOCATABLE      :: nocc_of_molecule
190      !INTEGER, DIMENSION(:,:), ALLOCATABLE      :: nvirt_of_molecule
191      !REAL(KIND=dp),DIMENSION(:,:), ALLOCATABLE :: mu_of_molecule
192
193      ! Descriptors of atoms
194      !INTEGER, DIMENSION(:), ALLOCATABLE        :: nbasis_of_atom
195      !INTEGER, DIMENSION(:,:), ALLOCATABLE      :: nocc_of_atom
196      !INTEGER, DIMENSION(:,:), ALLOCATABLE      :: nvirt_of_atom
197      !REAL(KIND=dp),DIMENSION(:,:), ALLOCATABLE :: mu_of_atom
198
199      ! All AO and MO matrices are distributed for parallel computations.
200      ! The following flags specify what constitues a block for a parallel
201      ! distribution. Both AOs and MOs can be divided into atomic or
202      ! molecular blocks. Domain blocks should be equal or larger than
203      ! the distribution blocks (otherwise retain_sparsity does not work).
204      ! Possible values: almo_mat_distr_atomic, almo_mat_distr_molecular
205      INTEGER :: mat_distr_aos, mat_distr_mos
206      ! Define mappping from a distribution block to a domain
207      INTEGER, DIMENSION(:), ALLOCATABLE :: domain_index_of_ao_block
208      INTEGER, DIMENSION(:), ALLOCATABLE :: domain_index_of_mo_block
209
210      LOGICAL              :: need_previous_ks
211      LOGICAL              :: need_virtuals
212      LOGICAL              :: need_orbital_energies
213      LOGICAL              :: s_inv_done
214      LOGICAL              :: s_sqrt_done
215      REAL(KIND=dp)        :: almo_scf_energy
216      LOGICAL              :: orthogonal_basis, fixed_mu
217      LOGICAL              :: return_orthogonalized_mos
218
219      !! Smearing control
220      !! smear flag allow to retrieve eigenvalues in almo_scf with diag algorithm and create occupation-scaled ALMO orbitals
221      LOGICAL               :: smear
222      !! store relevant smearing parameters
223      REAL(KIND=dp)         :: smear_e_temp !! electronic temperature, required for Fermi-Dirac
224      REAL(KIND=dp), DIMENSION(:), ALLOCATABLE    :: kTS !! electronic entropy contribution of each spin system
225      !! mo_energies(imo, ispin) stores the eigenvalue corresponding to the orbital imo with spin ispin
226      REAL(KIND=dp), DIMENSION(:, :), ALLOCATABLE :: mo_energies
227      !! since S-ALMO creates partially occupied orbitals, there is a need to store the real number of electron-pairs
228      !! of each spin and for each fragment
229      REAL(KIND=dp), DIMENSION(:, :), ALLOCATABLE :: real_ne_of_domain
230
231      ! Controls for the SCF procedure
232      REAL(KIND=dp)         :: eps_filter
233      INTEGER               :: xalmo_trial_wf
234      INTEGER               :: almo_scf_guess
235      REAL(KIND=dp)         :: eps_prev_guess
236      INTEGER               :: order_lanczos
237      REAL(KIND=dp)         :: matrix_iter_eps_error_factor
238      REAL(KIND=dp)         :: eps_lanczos
239      INTEGER               :: max_iter_lanczos
240      REAL(KIND=dp)         :: mixing_fraction
241      REAL(KIND=dp)         :: mu
242      ! SCF procedure for the block-diagonal ALMOs
243      INTEGER               :: almo_update_algorithm
244      ! SCF procedure for the quenched ALMOs (xALMOs)
245      INTEGER               :: xalmo_update_algorithm
246      ! mo overlap inversion algorithm
247      INTEGER               :: sigma_inv_algorithm
248
249      ! ALMO SCF delocalization control
250      LOGICAL               :: perturbative_delocalization
251      INTEGER               :: quencher_radius_type
252      REAL(KIND=dp)         :: quencher_r0_factor, &
253                               quencher_r1_factor, &
254                               !quencher_r0_shift,&
255                               !quencher_r1_shift,&
256                               quencher_s0, &
257                               quencher_s1, &
258                               envelope_amplitude
259
260      ! guess options
261      TYPE(almo_scf_history_type) :: almo_history
262      TYPE(almo_scf_history_type) :: xalmo_history
263      INTEGER :: almo_extrapolation_order
264      INTEGER :: xalmo_extrapolation_order
265
266      ! forces
267      LOGICAL :: calc_forces
268
269      !!!!!!!!!!!!!!!!!!!!!!!
270      !!!!!! MATRICES !!!!!!!
271      !!!!!!!!!!!!!!!!!!!!!!!
272
273      ! AO overlap NxN
274      TYPE(dbcsr_type), DIMENSION(1)   :: matrix_s
275      TYPE(dbcsr_type), DIMENSION(1)   :: matrix_s_inv
276      TYPE(dbcsr_type), DIMENSION(1)   :: matrix_s_sqrt
277      TYPE(dbcsr_type), DIMENSION(1)   :: matrix_s_sqrt_inv
278      ! block-diagonal AO overlap NxN
279      TYPE(dbcsr_type), DIMENSION(1)   :: matrix_s_blk
280      TYPE(dbcsr_type), DIMENSION(1)   :: matrix_s_blk_inv
281      TYPE(dbcsr_type), DIMENSION(1)   :: matrix_s_blk_sqrt
282      TYPE(dbcsr_type), DIMENSION(1)   :: matrix_s_blk_sqrt_inv
283
284      ! occupied ALMO coeff NxOCC (alpha,beta - if necessary)
285      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE :: matrix_t_blk
286      ! occupied MO coeff NxOCC (alpha,beta - if necessary)
287      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE :: matrix_t
288      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE :: matrix_t_tr
289      ! MO overlap OCCxOCC and its inverse (alpha, beta - if necessary)
290      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE :: matrix_sigma, &
291                                                     matrix_sigma_inv, &
292                                                     matrix_sigma_sqrt, &
293                                                     matrix_sigma_sqrt_inv, &
294                                                     matrix_sigma_blk, &
295                                                     matrix_sigma_inv_0deloc
296
297      ! error vector (alpha,beta - if necessary)
298      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE :: matrix_err_blk
299      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE :: matrix_err_xx
300
301      ! MO overlap VIRTxVIRT and its derivatives
302      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE :: matrix_sigma_vv, &
303                                                     matrix_sigma_vv_blk, &
304                                                     matrix_sigma_vv_sqrt, &
305                                                     matrix_sigma_vv_sqrt_inv
306
307      ! template of various VIRT x VIR matrices
308      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE :: matrix_vv_full_blk, &
309                                                     matrix_vv_disc_blk, &
310                                                     matrix_vv_disc
311
312      ! VIRT-OCC MO overlap
313      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE :: matrix_vo, matrix_ov
314      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE :: matrix_ov_full, &
315                                                     matrix_ov_disc
316      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE :: matrix_x
317
318      ! VIRT_DISC x VIRT_RETAINED
319      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE :: matrix_k_blk
320      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE :: matrix_k_tr
321      ! matrix_k_blk_ones is blocked with all elements equal to 1.0
322      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE :: matrix_k_blk_ones
323
324      ! virtual ALMO coeff NxV
325      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE :: matrix_v_blk, &
326                                                     matrix_v, &
327                                                     matrix_v_full_blk, &
328                                                     matrix_v_disc, &
329                                                     matrix_v_disc_blk
330
331      ! kohn-sham matrix (alpha,beta - if necessary)
332      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE :: matrix_ks
333      ! the diff between ks_blk and ks_0deloc is that blk is a blocked matrix
334      ! 0deloc stores the matrix that correponds to zero-delocalization state
335      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE :: matrix_ks_blk
336      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE :: matrix_ks_0deloc
337      ! density NxN (alpha,beta - if necessary)
338      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE :: matrix_p
339      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE :: matrix_p_blk
340
341      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE :: matrix_eoo
342      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE :: matrix_evv_full
343
344      ! preconditioner for k-optimization
345      ! RZK-warning: do they have to be stored?
346      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE :: opt_k_t_rr, &
347                                                     opt_k_t_dd, &
348                                                     opt_k_denom
349
350      ! second dimension is spin
351      TYPE(domain_submatrix_type), DIMENSION(:, :), ALLOCATABLE :: domain_preconditioner
352      TYPE(domain_submatrix_type), DIMENSION(:, :), ALLOCATABLE :: domain_s_inv
353      TYPE(domain_submatrix_type), DIMENSION(:, :), ALLOCATABLE :: domain_s_sqrt
354      TYPE(domain_submatrix_type), DIMENSION(:, :), ALLOCATABLE :: domain_s_sqrt_inv
355      TYPE(domain_submatrix_type), DIMENSION(:, :), ALLOCATABLE :: domain_ks_xx
356      TYPE(domain_submatrix_type), DIMENSION(:, :), ALLOCATABLE :: domain_t
357      TYPE(domain_submatrix_type), DIMENSION(:, :), ALLOCATABLE :: domain_err
358      TYPE(domain_submatrix_type), DIMENSION(:, :), ALLOCATABLE :: domain_r_down_up
359
360      INTEGER, DIMENSION(:), ALLOCATABLE                       :: cpu_of_domain
361
362      ! Options for various subsection options collected neatly
363      TYPE(almo_analysis_type)                       :: almo_analysis
364      TYPE(penalty_type)                             :: penalty
365
366      ! Options for various optimizers collected neatly
367      TYPE(optimizer_options_type)                   :: opt_block_diag_diis
368      TYPE(optimizer_options_type)                   :: opt_block_diag_pcg
369      TYPE(optimizer_options_type)                   :: opt_xalmo_diis
370      TYPE(optimizer_options_type)                   :: opt_xalmo_pcg
371      TYPE(optimizer_options_type)                   :: opt_xalmo_newton_pcg_solver
372      TYPE(optimizer_options_type)                   :: opt_k_pcg
373
374      ! keywords that control electron delocalization treatment
375      ! RZK-warning: many of these varibles should be collected
376      !  into an optimizer_options_type variable
377      INTEGER         :: deloc_method
378      LOGICAL         :: deloc_use_occ_orbs
379      LOGICAL         :: deloc_cayley_use_virt_orbs
380      INTEGER         :: deloc_cayley_tensor_type
381      LOGICAL         :: deloc_cayley_linear
382      INTEGER         :: deloc_cayley_conjugator
383      REAL(KIND=dp)   :: deloc_cayley_eps_convergence
384      INTEGER         :: deloc_cayley_max_iter
385      INTEGER         :: deloc_truncate_virt
386      INTEGER         :: deloc_virt_per_domain
387      LOGICAL         :: deloc_cayley_occ_precond
388      LOGICAL         :: deloc_cayley_vir_precond
389
390      !! keywords that control optimization of retained orbitals
391      INTEGER         :: opt_k_conjugator !-> conjugartor
392      REAL(KIND=dp)   :: opt_k_eps_convergence !-> eps_error
393      REAL(KIND=dp)   :: opt_k_trial_step_size !-> lin_search_step_size_guess
394      INTEGER         :: opt_k_max_iter !-> max_iter
395      INTEGER         :: opt_k_outer_max_iter !-> max_iter for a separate 'outer' optimizer
396      REAL(KIND=dp)   :: opt_k_trial_step_size_multiplier !-> ?
397      INTEGER         :: opt_k_conj_iter_start !-> ?
398      INTEGER         :: opt_k_prec_iter_start !-> ?
399      INTEGER         :: opt_k_conj_iter_freq !-> ?
400      INTEGER         :: opt_k_prec_iter_freq !-> ?
401
402      ! development keywords
403      INTEGER         :: integer01
404      INTEGER         :: integer02
405      INTEGER         :: integer03
406      INTEGER         :: integer04
407      INTEGER         :: integer05
408      REAL(KIND=dp)   :: real01
409      REAL(KIND=dp)   :: real02
410      REAL(KIND=dp)   :: real03
411      REAL(KIND=dp)   :: real04
412      REAL(KIND=dp)   :: real05
413      LOGICAL         :: logical01
414      LOGICAL         :: logical02
415      LOGICAL         :: logical03
416      LOGICAL         :: logical04
417      LOGICAL         :: logical05
418
419   END TYPE almo_scf_env_type
420
421CONTAINS
422
423! **************************************************************************************************
424!> \brief Prints out the options of an optimizer
425!> \param optimizer   options to print
426!> \param unit_nr   output stream
427!> \par History
428!>       2014.10 created [Rustam Z Khaliullin]
429!> \author Rustam Z Khaliullin
430! **************************************************************************************************
431   SUBROUTINE print_optimizer_options(optimizer, unit_nr)
432
433      TYPE(optimizer_options_type), INTENT(IN)           :: optimizer
434      INTEGER, INTENT(IN)                                :: unit_nr
435
436      CHARACTER(len=*), PARAMETER :: routineN = 'print_optimizer_options', &
437         routineP = moduleN//':'//routineN
438
439      CHARACTER(33)                                      :: conj_string, prec_string, type_string
440
441      IF (unit_nr .GT. 0) THEN
442
443         SELECT CASE (optimizer%optimizer_type)
444         CASE (optimizer_diis)
445            type_string = "DIIS"
446         CASE (optimizer_pcg)
447            type_string = "PCG"
448         END SELECT
449
450         WRITE (unit_nr, '(T4,A,T48,A33)') "optimizer type:", TRIM(type_string)
451         WRITE (unit_nr, '(T4,A,T48,I33)') "maximum iterations:", optimizer%max_iter
452         WRITE (unit_nr, '(T4,A,T48,E33.3)') "target error:", optimizer%eps_error
453
454         SELECT CASE (optimizer%optimizer_type)
455         CASE (optimizer_diis)
456
457            WRITE (unit_nr, '(T4,A,T48,I33)') "maximum DIIS history:", optimizer%ndiis
458
459         CASE (optimizer_pcg)
460
461            WRITE (unit_nr, '(T4,A,T48,E33.3)') "line search step size guess:", &
462               optimizer%lin_search_step_size_guess
463            WRITE (unit_nr, '(T4,A,T48,E33.3)') "line search target error:", &
464               optimizer%lin_search_eps_error
465            WRITE (unit_nr, '(T4,A,T48,I33)') "maximum outer loop iterations:", &
466               optimizer%max_iter_outer_loop
467
468            SELECT CASE (optimizer%preconditioner)
469            CASE (xalmo_prec_zero)
470               prec_string = "NONE"
471            CASE (xalmo_prec_domain)
472               prec_string = "0.5 KS + 0.5 S, DOMAINS"
473            CASE (xalmo_prec_full)
474               prec_string = "0.5 KS + 0.5 S, FULL"
475            END SELECT
476            WRITE (unit_nr, '(T4,A,T48,A33)') "preconditioner:", TRIM(prec_string)
477
478            SELECT CASE (optimizer%conjugator)
479            CASE (cg_zero)
480               conj_string = "Steepest descent"
481            CASE (cg_polak_ribiere)
482               conj_string = "Polak-Ribiere"
483            CASE (cg_fletcher_reeves)
484               conj_string = "Fletcher-Reeves"
485            CASE (cg_hestenes_stiefel)
486               conj_string = "Hestenes-Stiefel"
487            CASE (cg_fletcher)
488               conj_string = "Fletcher"
489            CASE (cg_liu_storey)
490               conj_string = "Liu-Storey"
491            CASE (cg_dai_yuan)
492               conj_string = "Dai-Yuan"
493            CASE (cg_hager_zhang)
494               conj_string = "Hager-Zhang"
495            END SELECT
496            WRITE (unit_nr, '(T4,A,T48,A33)') "conjugator:", TRIM(conj_string)
497
498         END SELECT !optimizer type
499
500      ENDIF
501
502   END SUBROUTINE print_optimizer_options
503
504! **************************************************************************************************
505!> \brief release the almo scf envirnoment
506!> \param almo_scf_env ...
507!> \par History
508!>       2016.11 created [Rustam Z Khaliullin]
509!> \author Rustam Z Khaliullin
510! **************************************************************************************************
511   SUBROUTINE almo_scf_env_release(almo_scf_env)
512      TYPE(almo_scf_env_type), POINTER                   :: almo_scf_env
513
514      CHARACTER(len=*), PARAMETER :: routineN = 'almo_scf_env_release', &
515         routineP = moduleN//':'//routineN
516
517      INTEGER                                            :: handle, ispin, istore
518
519      CALL timeset(routineN, handle)
520
521      ! delete history
522      DO ispin = 1, SIZE(almo_scf_env%almo_history%matrix_t)
523         DO istore = 1, MIN(almo_scf_env%almo_history%istore, almo_scf_env%almo_history%nstore)
524            CALL dbcsr_release(almo_scf_env%almo_history%matrix_p_up_down(ispin, istore))
525         ENDDO
526         IF (almo_scf_env%almo_history%istore .GT. 0) &
527            CALL dbcsr_release(almo_scf_env%almo_history%matrix_t(ispin))
528      ENDDO
529      DEALLOCATE (almo_scf_env%almo_history%matrix_p_up_down)
530      DEALLOCATE (almo_scf_env%almo_history%matrix_t)
531      ! delete xalmo history
532      DO ispin = 1, SIZE(almo_scf_env%xalmo_history%matrix_t)
533         DO istore = 1, MIN(almo_scf_env%xalmo_history%istore, almo_scf_env%xalmo_history%nstore)
534            CALL dbcsr_release(almo_scf_env%xalmo_history%matrix_p_up_down(ispin, istore))
535            !CALL dbcsr_release(almo_scf_env%xalmo_history%matrix_x(ispin, istore))
536         ENDDO
537         IF (almo_scf_env%xalmo_history%istore .GT. 0) &
538            CALL dbcsr_release(almo_scf_env%xalmo_history%matrix_t(ispin))
539      ENDDO
540      DEALLOCATE (almo_scf_env%xalmo_history%matrix_p_up_down)
541      !DEALLOCATE (almo_scf_env%xalmo_history%matrix_x)
542      DEALLOCATE (almo_scf_env%xalmo_history%matrix_t)
543
544      DEALLOCATE (almo_scf_env)
545
546      CALL timestop(handle)
547
548   END SUBROUTINE almo_scf_env_release
549
550END MODULE almo_scf_types
551
552