1!--------------------------------------------------------------------------------------------------!
2!   CP2K: A general program to perform molecular dynamics simulations                              !
3!   Copyright (C) 2000 - 2020  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, optimizer_trustr, &
23        trustr_cauchy, trustr_dogleg, trustr_steihaug, xalmo_prec_domain, xalmo_prec_full, &
24        xalmo_prec_zero
25   USE kinds,                           ONLY: dp
26#include "./base/base_uses.f90"
27
28   IMPLICIT NONE
29
30   PRIVATE
31
32   CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'almo_scf_types'
33
34   INTEGER, PARAMETER, PUBLIC   :: almo_mat_dim_aobasis = 1, &
35                                   almo_mat_dim_occ = 2, &
36                                   almo_mat_dim_virt = 3, &
37                                   almo_mat_dim_virt_full = 4, &
38                                   almo_mat_dim_domains = 5, &
39                                   almo_mat_dim_virt_disc = 6
40   REAL(KIND=dp), PARAMETER, PUBLIC :: almo_max_cutoff_multiplier = 2.2_dp
41
42   PUBLIC :: almo_scf_env_type, optimizer_options_type, &
43             print_optimizer_options, almo_scf_env_release, &
44             almo_scf_history_type
45
46   ! methods that add penalty terms to the energy functional
47   TYPE penalty_type
48
49      REAL(KIND=dp)      :: final_determinant, penalty_strength, &
50                            determinant_tolerance, penalty_strength_dec_factor, &
51                            compactification_filter_start
52      INTEGER            :: operator_type
53      LOGICAL            :: virtual_nlmos
54
55   END TYPE penalty_type
56
57   ! almo-based electronic structure analysis
58   TYPE almo_analysis_type
59
60      ! switch analysis on/off
61      LOGICAL :: do_analysis
62
63      INTEGER :: frozen_mo_energy_term
64
65   END TYPE almo_analysis_type
66
67   TYPE optimizer_options_type
68
69      REAL(KIND=dp)  :: eps_error, &
70                        eps_error_early, &
71                        lin_search_eps_error, &
72                        lin_search_step_size_guess, &
73                        rho_do_not_update, &
74                        model_grad_norm_ratio, &
75                        initial_trust_radius, &
76                        max_trust_radius, &
77                        neglect_threshold
78
79      INTEGER        :: optimizer_type ! diis, pcg, etc.
80      TYPE(penalty_type)  :: opt_penalty
81
82      INTEGER        :: preconditioner, & ! preconditioner type
83                        conjugator, & ! conjugator type
84                        max_iter, &
85                        max_iter_early, &
86                        max_iter_outer_loop, &
87                        trustr_algorithm, &
88                        ndiis ! diis history length
89
90      LOGICAL        :: early_stopping_on = .FALSE.
91
92   END TYPE optimizer_options_type
93
94   TYPE almo_scf_history_type
95      INTEGER :: istore, nstore
96      TYPE(dbcsr_type), DIMENSION(:, :), ALLOCATABLE :: matrix_p_up_down
97      !TYPE(dbcsr_type), DIMENSION(:, :), ALLOCATABLE :: matrix_x
98      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE :: matrix_t
99   END TYPE
100
101   ! the structure contains general info about the system
102   TYPE almo_scf_env_type
103
104      TYPE(cp_para_env_type), POINTER  :: para_env
105      TYPE(cp_blacs_env_type), POINTER  :: blacs_env
106
107      INTEGER :: nspins, nelectrons_total, naos
108      INTEGER :: natoms, nmolecules
109      INTEGER, DIMENSION(2) :: nelectrons_spin
110
111      ! Definitions:
112      ! I.  Domain - a subset of basis functions (e.g. AOs),
113      ! II. Group  - a subset of electrons delocalized within a domain.
114      !
115      ! The following variables specify the group-domain structure
116      ! of the system. Several rules must be obeyed:
117      ! 1. There should be no zero domains (i.e. domain contains at least one AO).
118      ! 2. There should be no empty domains (i.e. all domains must be populated
119      !     by at least one electron).
120      ! 3. If two groups are localized within the same domain they are combined
121      ! It follows that the number of domains is equal to the number of groups
122      !
123      ! Number of domains
124      INTEGER :: ndomains
125
126      ! List of atoms, whose basis functions are included into the domain.
127      ! It is assumed that:
128      !   (a) basis functions are localized and atom-labeled,
129      !   (b) basis functions are grouped into atomic sets (i.e. if a basis
130      !       function on an atom is in domain A then all basis functions on
131      !       this atom are in domain A)
132      !TYPE(domain_list_type), DIMENSION(:), ALLOCATABLE   :: atom_list_of_domain
133      ! List of basis functions included into the domain
134      !TYPE(domain_list_type), DIMENSION(:), ALLOCATABLE   :: basis_list_of_domain
135
136      ! Number of electrons of each spin for a given domain (second dim is spin).
137      ! Note that some domains can be populated only with alpha or beta electrons.
138      INTEGER, DIMENSION(:, :), ALLOCATABLE                :: nocc_of_domain
139      ! Number of basis functions for a given domain
140      INTEGER, DIMENSION(:), ALLOCATABLE                  :: nbasis_of_domain
141      ! Define number of virtuals for a given domain: nvirt = nbasis - nocc
142      INTEGER, DIMENSION(:, :), ALLOCATABLE                :: nvirt_full_of_domain
143      ! Define the dimension of truncated virtual subspace for a given domain:
144      INTEGER, DIMENSION(:, :), ALLOCATABLE                :: nvirt_of_domain
145      ! Define the dimension of discarded virtual subspace for a given domain:
146      INTEGER, DIMENSION(:, :), ALLOCATABLE                :: nvirt_disc_of_domain
147      ! Each domain has its own mu - "fermi" level
148      REAL(KIND=dp), DIMENSION(:, :), ALLOCATABLE          :: mu_of_domain
149      INTEGER, DIMENSION(:), ALLOCATABLE                  :: first_atom_of_domain
150      INTEGER, DIMENSION(:), ALLOCATABLE                  :: last_atom_of_domain
151      ! The following arrays are useful only with non-overlapping domains
152      ! RZK-warning generalization is required
153      INTEGER, DIMENSION(:), ALLOCATABLE        :: domain_index_of_ao
154      INTEGER, DIMENSION(:), ALLOCATABLE        :: domain_index_of_atom
155
156      ! Charge of domains
157      INTEGER, DIMENSION(:), ALLOCATABLE                  :: charge_of_domain
158      ! Charge of domains
159      INTEGER, DIMENSION(:), ALLOCATABLE                  :: multiplicity_of_domain
160
161      ! The matrix contains information about the delocalization of
162      ! alpha and beta electrons.
163      ! Rows denote basis function, columns denote electrons.
164      ! Non-zero (j,i) entry means that electron j can delocalize over
165      ! basis function i. 0.0 means no delocalization
166      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE   :: quench_t
167      TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE   :: quench_t_blk
168      ! Local array for a compact description of quench_t
169      TYPE(domain_map_type), DIMENSION(:), ALLOCATABLE :: domain_map
170
171      ! Several special cases for the structure of the group-domain matrix:
172      ! 1. The basis functions can be grouped into:
173      !    a. molecular sets
174      !    b. atomic sets
175      ! 2. Electrons can be grouped into:
176      !    a. molecular sets
177      !    b. atomic sets
178      INTEGER :: domain_layout_mos, domain_layout_aos
179      ! ALMO  constraint type.
180      INTEGER :: constraint_type
181
182      ! Desciptors of molecules
183      !INTEGER, DIMENSION(:), ALLOCATABLE        :: molecule_index_of_atom
184      !INTEGER, DIMENSION(:), ALLOCATABLE        :: first_atom_of_molecule
185      !INTEGER, DIMENSION(:), ALLOCATABLE        :: nbasis_of_molecule
186      !INTEGER, DIMENSION(:,:), ALLOCATABLE      :: nocc_of_molecule
187      !INTEGER, DIMENSION(:,:), ALLOCATABLE      :: nvirt_of_molecule
188      !REAL(KIND=dp),DIMENSION(:,:), ALLOCATABLE :: mu_of_molecule
189
190      ! Descriptors of atoms
191      !INTEGER, DIMENSION(:), ALLOCATABLE        :: nbasis_of_atom
192      !INTEGER, DIMENSION(:,:), ALLOCATABLE      :: nocc_of_atom
193      !INTEGER, DIMENSION(:,:), ALLOCATABLE      :: nvirt_of_atom
194      !REAL(KIND=dp),DIMENSION(:,:), ALLOCATABLE :: mu_of_atom
195
196      ! All AO and MO matrices are distributed for parallel computations.
197      ! The following flags specify what constitues a block for a parallel
198      ! distribution. Both AOs and MOs can be divided into atomic or
199      ! molecular blocks. Domain blocks should be equal or larger than
200      ! the distribution blocks (otherwise retain_sparsity does not work).
201      ! Possible values: almo_mat_distr_atomic, almo_mat_distr_molecular
202      INTEGER :: mat_distr_aos, mat_distr_mos
203      ! Define mappping from a distribution block to a domain
204      INTEGER, DIMENSION(:), ALLOCATABLE :: domain_index_of_ao_block
205      INTEGER, DIMENSION(:), ALLOCATABLE :: domain_index_of_mo_block
206
207      LOGICAL              :: need_previous_ks
208      LOGICAL              :: need_virtuals
209      LOGICAL              :: need_orbital_energies
210      LOGICAL              :: s_inv_done
211      LOGICAL              :: s_sqrt_done
212      REAL(KIND=dp)        :: almo_scf_energy
213      LOGICAL              :: orthogonal_basis, fixed_mu
214      LOGICAL              :: return_orthogonalized_mos, construct_nlmos
215
216      !! Smearing control
217      !! smear flag allow to retrieve eigenvalues in almo_scf with diag algorithm and create occupation-scaled ALMO orbitals
218      LOGICAL               :: smear
219      !! store relevant smearing parameters
220      REAL(KIND=dp)         :: smear_e_temp !! electronic temperature, required for Fermi-Dirac
221      REAL(KIND=dp), DIMENSION(:), ALLOCATABLE    :: kTS !! electronic entropy contribution of each spin system
222      !! mo_energies(imo, ispin) stores the eigenvalue corresponding to the orbital imo with spin ispin
223      REAL(KIND=dp), DIMENSION(:, :), ALLOCATABLE :: mo_energies
224      !! since S-ALMO creates partially occupied orbitals, there is a need to store the real number of electron-pairs
225      !! of each spin and for each fragment
226      REAL(KIND=dp), DIMENSION(:, :), ALLOCATABLE :: real_ne_of_domain
227
228      ! Controls for the SCF procedure
229      REAL(KIND=dp)         :: eps_filter
230      INTEGER               :: xalmo_trial_wf
231      INTEGER               :: almo_scf_guess
232      REAL(KIND=dp)         :: eps_prev_guess
233      INTEGER               :: order_lanczos
234      REAL(KIND=dp)         :: matrix_iter_eps_error_factor
235      REAL(KIND=dp)         :: eps_lanczos
236      INTEGER               :: max_iter_lanczos
237      REAL(KIND=dp)         :: mixing_fraction
238      REAL(KIND=dp)         :: mu
239      ! SCF procedure for the block-diagonal ALMOs
240      INTEGER               :: almo_update_algorithm
241      ! SCF procedure for the quenched ALMOs (xALMOs)
242      INTEGER               :: xalmo_update_algorithm
243      ! mo overlap inversion algorithm
244      INTEGER               :: sigma_inv_algorithm
245
246      ! Determinant of the ALMO overlap matrix
247      REAL(KIND=dp)         :: overlap_determinant
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
365      ! Options for various optimizers collected neatly
366      TYPE(optimizer_options_type)                   :: opt_block_diag_diis
367      TYPE(optimizer_options_type)                   :: opt_block_diag_pcg
368      TYPE(optimizer_options_type)                   :: opt_xalmo_diis
369      TYPE(optimizer_options_type)                   :: opt_xalmo_pcg
370      TYPE(optimizer_options_type)                   :: opt_xalmo_trustr
371      TYPE(optimizer_options_type)                   :: opt_nlmo_pcg
372      TYPE(optimizer_options_type)                   :: opt_xalmo_newton_pcg_solver
373      TYPE(optimizer_options_type)                   :: opt_k_pcg
374
375      ! keywords that control electron delocalization treatment
376      ! RZK-warning: many of these varibles should be collected
377      !  into an optimizer_options_type variable
378      INTEGER         :: deloc_method
379      LOGICAL         :: deloc_use_occ_orbs
380      LOGICAL         :: deloc_cayley_use_virt_orbs
381      INTEGER         :: deloc_cayley_tensor_type
382      LOGICAL         :: deloc_cayley_linear
383      INTEGER         :: deloc_cayley_conjugator
384      REAL(KIND=dp)   :: deloc_cayley_eps_convergence
385      INTEGER         :: deloc_cayley_max_iter
386      INTEGER         :: deloc_truncate_virt
387      INTEGER         :: deloc_virt_per_domain
388      LOGICAL         :: deloc_cayley_occ_precond
389      LOGICAL         :: deloc_cayley_vir_precond
390
391      !! keywords that control optimization of retained orbitals
392      INTEGER         :: opt_k_conjugator !-> conjugartor
393      REAL(KIND=dp)   :: opt_k_eps_convergence !-> eps_error
394      REAL(KIND=dp)   :: opt_k_trial_step_size !-> lin_search_step_size_guess
395      INTEGER         :: opt_k_max_iter !-> max_iter
396      INTEGER         :: opt_k_outer_max_iter !-> max_iter for a separate 'outer' optimizer
397      REAL(KIND=dp)   :: opt_k_trial_step_size_multiplier !-> ?
398      INTEGER         :: opt_k_conj_iter_start !-> ?
399      INTEGER         :: opt_k_prec_iter_start !-> ?
400      INTEGER         :: opt_k_conj_iter_freq !-> ?
401      INTEGER         :: opt_k_prec_iter_freq !-> ?
402
403      ! development keywords
404      INTEGER         :: integer01
405      INTEGER         :: integer02
406      INTEGER         :: integer03
407      INTEGER         :: integer04
408      INTEGER         :: integer05
409      REAL(KIND=dp)   :: real01
410      REAL(KIND=dp)   :: real02
411      REAL(KIND=dp)   :: real03
412      REAL(KIND=dp)   :: real04
413      REAL(KIND=dp)   :: real05
414      LOGICAL         :: logical01
415      LOGICAL         :: logical02
416      LOGICAL         :: logical03
417      LOGICAL         :: logical04
418      LOGICAL         :: logical05
419
420   END TYPE almo_scf_env_type
421
422CONTAINS
423
424! **************************************************************************************************
425!> \brief Prints out the options of an optimizer
426!> \param optimizer   options to print
427!> \param unit_nr   output stream
428!> \par History
429!>       2014.10 created [Rustam Z Khaliullin]
430!> \author Rustam Z Khaliullin
431! **************************************************************************************************
432   SUBROUTINE print_optimizer_options(optimizer, unit_nr)
433
434      TYPE(optimizer_options_type), INTENT(IN)           :: optimizer
435      INTEGER, INTENT(IN)                                :: unit_nr
436
437      CHARACTER(len=*), PARAMETER :: routineN = 'print_optimizer_options', &
438         routineP = moduleN//':'//routineN
439
440      CHARACTER(33)                                      :: conj_string, prec_string, type_string
441
442      IF (unit_nr .GT. 0) THEN
443
444         SELECT CASE (optimizer%optimizer_type)
445         CASE (optimizer_diis)
446            type_string = "DIIS"
447         CASE (optimizer_pcg)
448            type_string = "PCG"
449         CASE (optimizer_trustr)
450            type_string = "TRUST REGION"
451         END SELECT
452
453         WRITE (unit_nr, '(T4,A,T48,A33)') "optimizer type:", TRIM(type_string)
454         WRITE (unit_nr, '(T4,A,T48,I33)') "maximum iterations:", optimizer%max_iter
455         WRITE (unit_nr, '(T4,A,T48,E33.3)') "target error:", optimizer%eps_error
456
457         IF (optimizer%optimizer_type .EQ. optimizer_diis) THEN
458
459            WRITE (unit_nr, '(T4,A,T48,I33)') "maximum DIIS history:", optimizer%ndiis
460
461         ENDIF
462
463         IF (optimizer%optimizer_type .EQ. optimizer_trustr .OR. &
464             optimizer%optimizer_type .EQ. optimizer_pcg) THEN
465
466            WRITE (unit_nr, '(T4,A,T48,I33)') "maximum outer loop iterations:", &
467               optimizer%max_iter_outer_loop
468
469            SELECT CASE (optimizer%preconditioner)
470            CASE (xalmo_prec_zero)
471               prec_string = "NONE"
472            CASE (xalmo_prec_domain)
473               prec_string = "0.5 KS + 0.5 S, DOMAINS"
474            CASE (xalmo_prec_full)
475               prec_string = "0.5 KS + 0.5 S, FULL"
476            END SELECT
477            WRITE (unit_nr, '(T4,A,T48,A33)') "preconditioner:", TRIM(prec_string)
478
479            SELECT CASE (optimizer%conjugator)
480            CASE (cg_zero)
481               conj_string = "Steepest descent"
482            CASE (cg_polak_ribiere)
483               conj_string = "Polak-Ribiere"
484            CASE (cg_fletcher_reeves)
485               conj_string = "Fletcher-Reeves"
486            CASE (cg_hestenes_stiefel)
487               conj_string = "Hestenes-Stiefel"
488            CASE (cg_fletcher)
489               conj_string = "Fletcher"
490            CASE (cg_liu_storey)
491               conj_string = "Liu-Storey"
492            CASE (cg_dai_yuan)
493               conj_string = "Dai-Yuan"
494            CASE (cg_hager_zhang)
495               conj_string = "Hager-Zhang"
496            END SELECT
497            WRITE (unit_nr, '(T4,A,T48,A33)') "conjugator:", TRIM(conj_string)
498
499         ENDIF
500
501         IF (optimizer%optimizer_type .EQ. optimizer_pcg) THEN
502
503            WRITE (unit_nr, '(T4,A,T48,E33.3)') "line search step size guess:", &
504               optimizer%lin_search_step_size_guess
505            WRITE (unit_nr, '(T4,A,T48,E33.3)') "line search target error:", &
506               optimizer%lin_search_eps_error
507
508         ENDIF
509
510         IF (optimizer%optimizer_type .EQ. optimizer_trustr) THEN
511
512            SELECT CASE (optimizer%trustr_algorithm)
513            CASE (trustr_steihaug)
514               conj_string = "Steihaug's CG"
515            CASE (trustr_cauchy)
516               conj_string = "Cauchy point"
517            CASE (trustr_dogleg)
518               conj_string = "Dogleg"
519            END SELECT
520            WRITE (unit_nr, '(T4,A,T48,A33)') "Subproblem algorithm:", TRIM(conj_string)
521
522            WRITE (unit_nr, '(T4,A,T48,E33.3)') "gradient decrease accepted:", &
523               optimizer%model_grad_norm_ratio
524            WRITE (unit_nr, '(T4,A,T48,E33.3)') "initial trust radius:", &
525               optimizer%initial_trust_radius
526            WRITE (unit_nr, '(T4,A,T48,E33.3)') "max trust radius:", &
527               optimizer%max_trust_radius
528            WRITE (unit_nr, '(T4,A,T48,E33.3)') "rho of no update lies between .0 and .25:", &
529               optimizer%rho_do_not_update
530
531         ENDIF
532
533      ENDIF
534
535   END SUBROUTINE print_optimizer_options
536
537! **************************************************************************************************
538!> \brief release the almo scf envirnoment
539!> \param almo_scf_env ...
540!> \par History
541!>       2016.11 created [Rustam Z Khaliullin]
542!> \author Rustam Z Khaliullin
543! **************************************************************************************************
544   SUBROUTINE almo_scf_env_release(almo_scf_env)
545      TYPE(almo_scf_env_type), POINTER                   :: almo_scf_env
546
547      CHARACTER(len=*), PARAMETER :: routineN = 'almo_scf_env_release', &
548         routineP = moduleN//':'//routineN
549
550      INTEGER                                            :: handle, ispin, istore
551
552      CALL timeset(routineN, handle)
553
554      ! delete history
555      DO ispin = 1, SIZE(almo_scf_env%almo_history%matrix_t)
556         DO istore = 1, MIN(almo_scf_env%almo_history%istore, almo_scf_env%almo_history%nstore)
557            CALL dbcsr_release(almo_scf_env%almo_history%matrix_p_up_down(ispin, istore))
558         ENDDO
559         IF (almo_scf_env%almo_history%istore .GT. 0) &
560            CALL dbcsr_release(almo_scf_env%almo_history%matrix_t(ispin))
561      ENDDO
562      DEALLOCATE (almo_scf_env%almo_history%matrix_p_up_down)
563      DEALLOCATE (almo_scf_env%almo_history%matrix_t)
564      ! delete xalmo history
565      DO ispin = 1, SIZE(almo_scf_env%xalmo_history%matrix_t)
566         DO istore = 1, MIN(almo_scf_env%xalmo_history%istore, almo_scf_env%xalmo_history%nstore)
567            CALL dbcsr_release(almo_scf_env%xalmo_history%matrix_p_up_down(ispin, istore))
568            !CALL dbcsr_release(almo_scf_env%xalmo_history%matrix_x(ispin, istore))
569         ENDDO
570         IF (almo_scf_env%xalmo_history%istore .GT. 0) &
571            CALL dbcsr_release(almo_scf_env%xalmo_history%matrix_t(ispin))
572      ENDDO
573      DEALLOCATE (almo_scf_env%xalmo_history%matrix_p_up_down)
574      !DEALLOCATE (almo_scf_env%xalmo_history%matrix_x)
575      DEALLOCATE (almo_scf_env%xalmo_history%matrix_t)
576
577      DEALLOCATE (almo_scf_env)
578
579      CALL timestop(handle)
580
581   END SUBROUTINE almo_scf_env_release
582
583END MODULE almo_scf_types
584
585