LCOV - code coverage report
Current view: top level - src - almo_scf.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:561f475) Lines: 83.5 % 928 775
Test Date: 2026-06-21 06:48:54 Functions: 93.8 % 16 15

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief Routines for all ALMO-based SCF methods
      10              : !>        'RZK-warning' marks unresolved issues
      11              : !> \par History
      12              : !>       2011.05 created [Rustam Z Khaliullin]
      13              : !> \author Rustam Z Khaliullin
      14              : ! **************************************************************************************************
      15              : MODULE almo_scf
      16              :    USE almo_scf_methods,                ONLY: almo_scf_p_blk_to_t_blk,&
      17              :                                               almo_scf_t_rescaling,&
      18              :                                               almo_scf_t_to_proj,&
      19              :                                               distribute_domains,&
      20              :                                               orthogonalize_mos
      21              :    USE almo_scf_optimizer,              ONLY: almo_scf_block_diagonal,&
      22              :                                               almo_scf_construct_nlmos,&
      23              :                                               almo_scf_xalmo_eigensolver,&
      24              :                                               almo_scf_xalmo_pcg,&
      25              :                                               almo_scf_xalmo_trustr
      26              :    USE almo_scf_qs,                     ONLY: almo_dm_to_almo_ks,&
      27              :                                               almo_scf_construct_quencher,&
      28              :                                               calculate_w_matrix_almo,&
      29              :                                               construct_qs_mos,&
      30              :                                               init_almo_ks_matrix_via_qs,&
      31              :                                               matrix_almo_create,&
      32              :                                               matrix_qs_to_almo
      33              :    USE almo_scf_types,                  ONLY: almo_mat_dim_aobasis,&
      34              :                                               almo_mat_dim_occ,&
      35              :                                               almo_mat_dim_virt,&
      36              :                                               almo_mat_dim_virt_disc,&
      37              :                                               almo_mat_dim_virt_full,&
      38              :                                               almo_scf_env_type,&
      39              :                                               optimizer_options_type,&
      40              :                                               print_optimizer_options
      41              :    USE atomic_kind_types,               ONLY: atomic_kind_type
      42              :    USE bibliography,                    ONLY: Khaliullin2013,&
      43              :                                               Kolafa2004,&
      44              :                                               Kuhne2007,&
      45              :                                               Rullan2026,&
      46              :                                               Scheiber2018,&
      47              :                                               Staub2019,&
      48              :                                               cite_reference
      49              :    USE cp_blacs_env,                    ONLY: cp_blacs_env_release
      50              :    USE cp_control_types,                ONLY: dft_control_type
      51              :    USE cp_dbcsr_api,                    ONLY: &
      52              :         dbcsr_add, dbcsr_binary_read, dbcsr_copy, dbcsr_create, dbcsr_distribution_type, &
      53              :         dbcsr_filter, dbcsr_finalize, dbcsr_get_info, dbcsr_iterator_blocks_left, &
      54              :         dbcsr_iterator_next_block, dbcsr_iterator_start, dbcsr_iterator_stop, dbcsr_iterator_type, &
      55              :         dbcsr_multiply, dbcsr_p_type, dbcsr_release, dbcsr_scale, dbcsr_set, dbcsr_type, &
      56              :         dbcsr_type_no_symmetry, dbcsr_type_symmetric, dbcsr_work_create
      57              :    USE cp_dbcsr_contrib,                ONLY: dbcsr_add_on_diag,&
      58              :                                               dbcsr_checksum,&
      59              :                                               dbcsr_init_random,&
      60              :                                               dbcsr_reserve_all_blocks
      61              :    USE cp_dbcsr_diag,                   ONLY: cp_dbcsr_syevd
      62              :    USE cp_dbcsr_operations,             ONLY: copy_dbcsr_to_fm
      63              :    USE cp_fm_types,                     ONLY: cp_fm_type
      64              :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      65              :                                               cp_logger_get_default_unit_nr,&
      66              :                                               cp_logger_type
      67              :    USE domain_submatrix_methods,        ONLY: init_submatrices,&
      68              :                                               release_submatrices
      69              :    USE input_constants,                 ONLY: &
      70              :         almo_deloc_none, almo_deloc_scf, almo_deloc_x, almo_deloc_x_then_scf, &
      71              :         almo_deloc_xalmo_1diag, almo_deloc_xalmo_scf, almo_deloc_xalmo_x, almo_deloc_xk, &
      72              :         almo_domain_layout_molecular, almo_mat_distr_atomic, almo_mat_distr_molecular, &
      73              :         almo_scf_diag, almo_scf_dm_sign, almo_scf_pcg, almo_scf_skip, almo_scf_trustr, &
      74              :         atomic_guess, molecular_guess, optimizer_diis, optimizer_lin_eq_pcg, optimizer_pcg, &
      75              :         optimizer_trustr, restart_guess, smear_fermi_dirac, virt_full, virt_number, virt_occ_size, &
      76              :         xalmo_case_block_diag, xalmo_case_fully_deloc, xalmo_case_normal, xalmo_trial_r0_out
      77              :    USE input_section_types,             ONLY: section_vals_type
      78              :    USE iterate_matrix,                  ONLY: invert_Hotelling,&
      79              :                                               matrix_sqrt_Newton_Schulz
      80              :    USE kinds,                           ONLY: default_path_length,&
      81              :                                               dp
      82              :    USE mathlib,                         ONLY: binomial
      83              :    USE message_passing,                 ONLY: mp_comm_type,&
      84              :                                               mp_para_env_release,&
      85              :                                               mp_para_env_type
      86              :    USE molecule_types,                  ONLY: get_molecule_set_info,&
      87              :                                               molecule_type
      88              :    USE mscfg_types,                     ONLY: get_matrix_from_submatrices,&
      89              :                                               molecular_scf_guess_env_type
      90              :    USE particle_types,                  ONLY: particle_type
      91              :    USE qs_atomic_block,                 ONLY: calculate_atomic_block_dm
      92              :    USE qs_environment_types,            ONLY: get_qs_env,&
      93              :                                               qs_environment_type
      94              :    USE qs_initial_guess,                ONLY: calculate_mopac_dm
      95              :    USE qs_kind_types,                   ONLY: qs_kind_type
      96              :    USE qs_mo_types,                     ONLY: get_mo_set,&
      97              :                                               mo_set_type
      98              :    USE qs_rho_types,                    ONLY: qs_rho_get,&
      99              :                                               qs_rho_type
     100              :    USE qs_scf_post_scf,                 ONLY: qs_scf_compute_properties
     101              :    USE qs_scf_types,                    ONLY: qs_scf_env_type
     102              : #include "./base/base_uses.f90"
     103              : 
     104              :    IMPLICIT NONE
     105              : 
     106              :    PRIVATE
     107              : 
     108              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'almo_scf'
     109              : 
     110              :    PUBLIC :: almo_entry_scf
     111              : 
     112              :    LOGICAL, PARAMETER :: debug_mode = .FALSE.
     113              :    LOGICAL, PARAMETER :: safe_mode = .FALSE.
     114              : 
     115              : CONTAINS
     116              : 
     117              : ! **************************************************************************************************
     118              : !> \brief The entry point into ALMO SCF routines
     119              : !> \param qs_env   pointer to the QS environment
     120              : !> \param calc_forces   calculate forces?
     121              : !> \par History
     122              : !>       2011.05 created [Rustam Z Khaliullin]
     123              : !> \author Rustam Z Khaliullin
     124              : ! **************************************************************************************************
     125          122 :    SUBROUTINE almo_entry_scf(qs_env, calc_forces)
     126              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     127              :       LOGICAL, INTENT(IN)                                :: calc_forces
     128              : 
     129              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'almo_entry_scf'
     130              : 
     131              :       INTEGER                                            :: handle
     132              :       TYPE(almo_scf_env_type), POINTER                   :: almo_scf_env
     133              : 
     134          122 :       CALL timeset(routineN, handle)
     135              : 
     136          122 :       CALL cite_reference(Khaliullin2013)
     137              : 
     138              :       ! get a pointer to the almo environment
     139          122 :       CALL get_qs_env(qs_env, almo_scf_env=almo_scf_env)
     140              : 
     141              :       ! initialize scf
     142          122 :       CALL almo_scf_init(qs_env, almo_scf_env, calc_forces)
     143              : 
     144              :       ! create the initial guess for ALMOs
     145          122 :       CALL almo_scf_initial_guess(qs_env, almo_scf_env)
     146              : 
     147              :       ! perform SCF for block diagonal ALMOs
     148          122 :       CALL almo_scf_main(qs_env, almo_scf_env)
     149              : 
     150              :       ! allow electron delocalization
     151          122 :       CALL almo_scf_delocalization(qs_env, almo_scf_env)
     152              : 
     153              :       ! construct NLMOs
     154          122 :       CALL construct_nlmos(qs_env, almo_scf_env)
     155              : 
     156              :       ! electron correlation methods
     157              :       !CALL almo_correlation_main(qs_env,almo_scf_env)
     158              : 
     159              :       ! do post scf processing
     160          122 :       CALL almo_scf_post(qs_env, almo_scf_env)
     161              : 
     162              :       ! clean up the mess
     163          122 :       CALL almo_scf_clean_up(almo_scf_env)
     164              : 
     165          122 :       CALL timestop(handle)
     166              : 
     167          122 :    END SUBROUTINE almo_entry_scf
     168              : 
     169              : ! **************************************************************************************************
     170              : !> \brief Initialization of the almo_scf_env_type.
     171              : !> \param qs_env ...
     172              : !> \param almo_scf_env ...
     173              : !> \param calc_forces ...
     174              : !> \par History
     175              : !>       2011.05 created [Rustam Z Khaliullin]
     176              : !>       2018.09 smearing support [Ruben Staub]
     177              : !> \author Rustam Z Khaliullin
     178              : ! **************************************************************************************************
     179          122 :    SUBROUTINE almo_scf_init(qs_env, almo_scf_env, calc_forces)
     180              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     181              :       TYPE(almo_scf_env_type), INTENT(INOUT)             :: almo_scf_env
     182              :       LOGICAL, INTENT(IN)                                :: calc_forces
     183              : 
     184              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'almo_scf_init'
     185              : 
     186              :       INTEGER                                            :: ao, handle, i, iao, idomain, ispin, &
     187              :                                                             multip, naos, natoms, ndomains, nelec, &
     188              :                                                             nelec_a, nelec_b, nmols, nspins, &
     189              :                                                             unit_nr
     190              :       TYPE(cp_logger_type), POINTER                      :: logger
     191          122 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_s
     192              :       TYPE(dft_control_type), POINTER                    :: dft_control
     193          122 :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
     194              :       TYPE(section_vals_type), POINTER                   :: input
     195              : 
     196          122 :       CALL timeset(routineN, handle)
     197              : 
     198              :       ! define the output_unit
     199          122 :       logger => cp_get_default_logger()
     200          122 :       IF (logger%para_env%is_source()) THEN
     201           61 :          unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
     202              :       ELSE
     203           61 :          unit_nr = -1
     204              :       END IF
     205              : 
     206              :       ! set optimizers' types
     207          122 :       almo_scf_env%opt_block_diag_diis%optimizer_type = optimizer_diis
     208          122 :       almo_scf_env%opt_block_diag_pcg%optimizer_type = optimizer_pcg
     209          122 :       almo_scf_env%opt_xalmo_diis%optimizer_type = optimizer_diis
     210          122 :       almo_scf_env%opt_xalmo_pcg%optimizer_type = optimizer_pcg
     211          122 :       almo_scf_env%opt_xalmo_trustr%optimizer_type = optimizer_trustr
     212          122 :       almo_scf_env%opt_nlmo_pcg%optimizer_type = optimizer_pcg
     213          122 :       almo_scf_env%opt_block_diag_trustr%optimizer_type = optimizer_trustr
     214          122 :       almo_scf_env%opt_xalmo_newton_pcg_solver%optimizer_type = optimizer_lin_eq_pcg
     215              : 
     216              :       ! get info from the qs_env
     217              :       CALL get_qs_env(qs_env, &
     218              :                       nelectron_total=almo_scf_env%nelectrons_total, &
     219              :                       matrix_s=matrix_s, &
     220              :                       dft_control=dft_control, &
     221              :                       molecule_set=molecule_set, &
     222              :                       input=input, &
     223              :                       has_unit_metric=almo_scf_env%orthogonal_basis, &
     224              :                       para_env=almo_scf_env%para_env, &
     225              :                       blacs_env=almo_scf_env%blacs_env, &
     226          122 :                       nelectron_spin=almo_scf_env%nelectrons_spin)
     227          122 :       CALL almo_scf_env%para_env%retain()
     228          122 :       CALL almo_scf_env%blacs_env%retain()
     229              : 
     230              :       ! copy basic quantities
     231          122 :       almo_scf_env%nspins = dft_control%nspins
     232          122 :       almo_scf_env%nmolecules = SIZE(molecule_set)
     233              :       CALL dbcsr_get_info(matrix_s(1)%matrix, &
     234          122 :                           nfullrows_total=naos, nblkrows_total=almo_scf_env%natoms)
     235          122 :       almo_scf_env%naos = naos
     236              :       !! retrieve smearing parameters, and check compatibility of methods requested
     237          122 :       almo_scf_env%smear = dft_control%smear
     238          122 :       IF (almo_scf_env%smear) THEN
     239            4 :          CALL cite_reference(Staub2019)
     240            4 :          IF ((almo_scf_env%almo_update_algorithm /= almo_scf_diag) .OR. &
     241              :              ((almo_scf_env%deloc_method /= almo_deloc_none) .AND. &
     242              :               (almo_scf_env%xalmo_update_algorithm /= almo_scf_diag))) THEN
     243            0 :             CPABORT("ALMO smearing is currently implemented for DIAG algorithm only")
     244              :          END IF
     245            4 :          IF (qs_env%scf_control%smear%method /= smear_fermi_dirac) THEN
     246            0 :             CPABORT("Only Fermi-Dirac smearing is currently compatible with ALMO")
     247              :          END IF
     248            4 :          almo_scf_env%smear_e_temp = qs_env%scf_control%smear%electronic_temperature
     249            4 :          IF ((almo_scf_env%mat_distr_aos /= almo_mat_distr_molecular) .OR. &
     250              :              (almo_scf_env%domain_layout_mos /= almo_domain_layout_molecular)) THEN
     251            0 :             CPABORT("ALMO smearing was designed to work with molecular fragments only")
     252              :          END IF
     253              :       END IF
     254              : 
     255              :       ! convenient local varibales
     256          122 :       nmols = almo_scf_env%nmolecules
     257          122 :       natoms = almo_scf_env%natoms
     258              : 
     259              :       ! Define groups: either atomic or molecular
     260          122 :       IF (almo_scf_env%domain_layout_mos == almo_domain_layout_molecular) THEN
     261          122 :          almo_scf_env%ndomains = almo_scf_env%nmolecules
     262              :       ELSE
     263            0 :          almo_scf_env%ndomains = almo_scf_env%natoms
     264              :       END IF
     265              : 
     266          122 :       IF (ALLOCATED(almo_scf_env%activate) .AND. almo_scf_env%activate(1) > 1) THEN
     267            0 :          DEALLOCATE (almo_scf_env%activate)
     268              :       END IF
     269              : 
     270          122 :       IF (.NOT. ALLOCATED(almo_scf_env%activate)) THEN
     271           50 :          ALLOCATE (almo_scf_env%activate(1))
     272          100 :          almo_scf_env%activate = 0
     273              :       END IF
     274              : 
     275          122 :       IF (almo_scf_env%activate(1) == 1) THEN
     276            6 :          CALL cite_reference(Rullan2026)
     277            6 :          ndomains = SIZE(almo_scf_env%multiplicity_of_domain)
     278            6 :          nspins = SIZE(almo_scf_env%multiplicity_of_domain)
     279              :       ELSE
     280          116 :          nspins = almo_scf_env%nspins
     281          116 :          ndomains = almo_scf_env%ndomains
     282              :       END IF
     283              : 
     284          122 :       IF (almo_scf_env%activate(1) == 0) THEN
     285              : 
     286          348 :          ALLOCATE (almo_scf_env%charge_of_domain(ndomains))
     287          232 :          ALLOCATE (almo_scf_env%multiplicity_of_domain(ndomains))
     288              :       END IF
     289              : 
     290              :       ! allocate domain descriptors
     291              : 
     292          366 :       ALLOCATE (almo_scf_env%domain_index_of_atom(natoms))
     293          366 :       ALLOCATE (almo_scf_env%domain_index_of_ao(naos))
     294          366 :       ALLOCATE (almo_scf_env%first_atom_of_domain(ndomains))
     295          244 :       ALLOCATE (almo_scf_env%last_atom_of_domain(ndomains))
     296          244 :       ALLOCATE (almo_scf_env%nbasis_of_domain(ndomains))
     297          488 :       ALLOCATE (almo_scf_env%nocc_of_domain(ndomains, nspins)) !! with smearing, nb of available orbitals for occupation
     298          488 :       ALLOCATE (almo_scf_env%real_ne_of_domain(ndomains, nspins)) !! with smearing, nb of fully-occupied orbitals
     299          366 :       ALLOCATE (almo_scf_env%nvirt_full_of_domain(ndomains, nspins))
     300          366 :       ALLOCATE (almo_scf_env%nvirt_of_domain(ndomains, nspins))
     301          366 :       ALLOCATE (almo_scf_env%nvirt_disc_of_domain(ndomains, nspins))
     302          366 :       ALLOCATE (almo_scf_env%mu_of_domain(ndomains, nspins))
     303          244 :       ALLOCATE (almo_scf_env%cpu_of_domain(ndomains))
     304              : 
     305              :       ! fill out domain descriptors and group descriptors
     306          122 :       IF (almo_scf_env%domain_layout_mos == almo_domain_layout_molecular) THEN
     307              :          ! get domain info from molecule_set
     308          122 :          IF (almo_scf_env%activate(1) == 1) THEN
     309              :             CALL get_molecule_set_info(molecule_set, &
     310              :                                        atom_to_mol=almo_scf_env%domain_index_of_atom, &
     311              :                                        mol_to_first_atom=almo_scf_env%first_atom_of_domain, &
     312              :                                        mol_to_last_atom=almo_scf_env%last_atom_of_domain, &
     313              :                                        mol_to_nelectrons=almo_scf_env%nocc_of_domain(1:ndomains, 1), &
     314            6 :                                        mol_to_nbasis=almo_scf_env%nbasis_of_domain)
     315              : 
     316              :          ELSE
     317              :             CALL get_molecule_set_info(molecule_set, &
     318              :                                        atom_to_mol=almo_scf_env%domain_index_of_atom, &
     319              :                                        mol_to_first_atom=almo_scf_env%first_atom_of_domain, &
     320              :                                        mol_to_last_atom=almo_scf_env%last_atom_of_domain, &
     321              :                                        mol_to_nelectrons=almo_scf_env%nocc_of_domain(1:ndomains, 1), &
     322              :                                        mol_to_nbasis=almo_scf_env%nbasis_of_domain, &
     323              :                                        mol_to_charge=almo_scf_env%charge_of_domain, &
     324          116 :                                        mol_to_multiplicity=almo_scf_env%multiplicity_of_domain)
     325              :          END IF
     326              :          ! calculate number of alpha and beta occupied orbitals from
     327              :          ! the number of electrons and multiplicity of each molecule
     328              :          ! Na + Nb = Ne
     329              :          ! Na - Nb = Mult - 1 (assume Na > Nb as we do not have more info from get_molecule_set_info)
     330          944 :          DO idomain = 1, ndomains
     331          822 :             IF (almo_scf_env%activate(1) == 1) THEN
     332           12 :                nelec = almo_scf_env%nocc_of_domain(idomain, 1) - almo_scf_env%charge_of_domain(idomain)
     333              :             ELSE
     334          810 :                nelec = almo_scf_env%nocc_of_domain(idomain, 1)
     335              :             END IF
     336              : 
     337          822 :             multip = almo_scf_env%multiplicity_of_domain(idomain)
     338          822 :             nelec_a = (nelec + multip - 1)/2
     339              : 
     340              :             !! Initializing an occupation-rescaling trick if smearing is on
     341          944 :             IF (almo_scf_env%smear) THEN
     342            8 :                CPWARN_IF(multip > 1, "BEWARE: Non singlet state detected, treating it as closed-shell")
     343              :                !! Save real number of electrons of each spin, as it is required for Fermi-dirac smearing
     344              :                !! BEWARE : Non singlet states are allowed but treated as closed-shell
     345           16 :                almo_scf_env%real_ne_of_domain(idomain, :) = REAL(nelec, KIND=dp)/2.0_dp
     346              :                !! Add a number of added_mos equal to the number of atoms in domain
     347              :                !! (since fragments were computed this way with smearing)
     348              :                almo_scf_env%nocc_of_domain(idomain, :) = CEILING(almo_scf_env%real_ne_of_domain(idomain, :)) &
     349              :                                                          + (almo_scf_env%last_atom_of_domain(idomain) &
     350           16 :                                                             - almo_scf_env%first_atom_of_domain(idomain) + 1)
     351              :             ELSE
     352          814 :                almo_scf_env%nocc_of_domain(idomain, 1) = nelec_a
     353          814 :                nelec_b = nelec - nelec_a
     354          814 :                IF (almo_scf_env%activate(1) == 1) THEN
     355           12 :                   almo_scf_env%nocc_of_domain(idomain, 2) = nelec_b
     356              :                END IF
     357              : 
     358          814 :                IF (nelec_a /= nelec_b) THEN
     359            4 :                   IF (nspins == 1) THEN
     360              : 
     361            0 :                      CPABORT("odd e- -- use unrestricted methods")
     362              :                   END IF
     363              : 
     364              :                END IF
     365              :             END IF
     366              :          END DO
     367          250 :          DO ispin = 1, nspins
     368              :             ! take care of the full virtual subspace
     369              :             almo_scf_env%nvirt_full_of_domain(:, ispin) = &
     370              :                almo_scf_env%nbasis_of_domain(:) - &
     371          962 :                almo_scf_env%nocc_of_domain(:, ispin)
     372              :             ! and the truncated virtual subspace
     373          122 :             SELECT CASE (almo_scf_env%deloc_truncate_virt)
     374              :             CASE (virt_full)
     375              :                almo_scf_env%nvirt_of_domain(:, ispin) = &
     376          962 :                   almo_scf_env%nvirt_full_of_domain(:, ispin)
     377          962 :                almo_scf_env%nvirt_disc_of_domain(:, ispin) = 0
     378              :             CASE (virt_number)
     379            0 :                DO idomain = 1, ndomains
     380              :                   almo_scf_env%nvirt_of_domain(idomain, ispin) = &
     381              :                      MIN(almo_scf_env%deloc_virt_per_domain, &
     382            0 :                          almo_scf_env%nvirt_full_of_domain(idomain, ispin))
     383              :                   almo_scf_env%nvirt_disc_of_domain(idomain, ispin) = &
     384              :                      almo_scf_env%nvirt_full_of_domain(idomain, ispin) - &
     385            0 :                      almo_scf_env%nvirt_of_domain(idomain, ispin)
     386              :                END DO
     387              :             CASE (virt_occ_size)
     388            0 :                DO idomain = 1, ndomains
     389              :                   almo_scf_env%nvirt_of_domain(idomain, ispin) = &
     390              :                      MIN(almo_scf_env%nocc_of_domain(idomain, ispin), &
     391            0 :                          almo_scf_env%nvirt_full_of_domain(idomain, ispin))
     392              :                   almo_scf_env%nvirt_disc_of_domain(idomain, ispin) = &
     393              :                      almo_scf_env%nvirt_full_of_domain(idomain, ispin) - &
     394            0 :                      almo_scf_env%nvirt_of_domain(idomain, ispin)
     395              :                END DO
     396              :             CASE DEFAULT
     397          128 :                CPABORT("illegal method for virtual space truncation")
     398              :             END SELECT
     399              :          END DO ! spin
     400              :       ELSE ! domains are atomic
     401              :          ! RZK-warning do the same for atomic domains/groups
     402            0 :          almo_scf_env%domain_index_of_atom(1:natoms) = [(i, i=1, natoms)]
     403              :       END IF
     404              : 
     405              :       ao = 1
     406          944 :       DO idomain = 1, ndomains
     407         9340 :          DO iao = 1, almo_scf_env%nbasis_of_domain(idomain)
     408         8396 :             almo_scf_env%domain_index_of_ao(ao) = idomain
     409         9218 :             ao = ao + 1
     410              :          END DO
     411              :       END DO
     412              : 
     413         1084 :       almo_scf_env%mu_of_domain(:, :) = almo_scf_env%mu
     414              : 
     415              :       ! build domain (i.e. layout) indices for distribution blocks
     416              :       ! ao blocks
     417          122 :       IF (almo_scf_env%mat_distr_aos == almo_mat_distr_atomic) THEN
     418            0 :          ALLOCATE (almo_scf_env%domain_index_of_ao_block(natoms))
     419              :          almo_scf_env%domain_index_of_ao_block(:) = &
     420            0 :             almo_scf_env%domain_index_of_atom(:)
     421          122 :       ELSE IF (almo_scf_env%mat_distr_aos == almo_mat_distr_molecular) THEN
     422          366 :          ALLOCATE (almo_scf_env%domain_index_of_ao_block(nmols))
     423              :          ! if distr blocks are molecular then domain layout is also molecular
     424         1766 :          almo_scf_env%domain_index_of_ao_block(:) = [(i, i=1, nmols)]
     425              :       END IF
     426              :       ! mo blocks
     427          122 :       IF (almo_scf_env%mat_distr_mos == almo_mat_distr_atomic) THEN
     428            0 :          ALLOCATE (almo_scf_env%domain_index_of_mo_block(natoms))
     429              :          almo_scf_env%domain_index_of_mo_block(:) = &
     430            0 :             almo_scf_env%domain_index_of_atom(:)
     431          122 :       ELSE IF (almo_scf_env%mat_distr_mos == almo_mat_distr_molecular) THEN
     432          366 :          ALLOCATE (almo_scf_env%domain_index_of_mo_block(nmols))
     433              :          ! if distr blocks are molecular then domain layout is also molecular
     434         1766 :          almo_scf_env%domain_index_of_mo_block(:) = [(i, i=1, nmols)]
     435              :       END IF
     436              : 
     437              :       ! set all flags
     438              :       !almo_scf_env%need_previous_ks=.FALSE.
     439              :       !IF (almo_scf_env%deloc_method==almo_deloc_harris) THEN
     440          122 :       almo_scf_env%need_previous_ks = .TRUE.
     441              :       !ENDIF
     442              : 
     443              :       !almo_scf_env%need_virtuals=.FALSE.
     444              :       !almo_scf_env%need_orbital_energies=.FALSE.
     445              :       !IF (almo_scf_env%almo_update_algorithm==almo_scf_diag) THEN
     446          122 :       almo_scf_env%need_virtuals = .TRUE.
     447          122 :       almo_scf_env%need_orbital_energies = .TRUE.
     448              :       !ENDIF
     449              : 
     450          122 :       almo_scf_env%calc_forces = calc_forces
     451          122 :       IF (calc_forces) THEN
     452           66 :          CALL cite_reference(Scheiber2018)
     453              :          IF (almo_scf_env%deloc_method == almo_deloc_x .OR. &
     454           66 :              almo_scf_env%deloc_method == almo_deloc_xalmo_x .OR. &
     455              :              almo_scf_env%deloc_method == almo_deloc_xalmo_1diag) THEN
     456            0 :             CPABORT("Forces for perturbative methods are NYI. Change DELOCALIZE_METHOD")
     457              :          END IF
     458              :          ! switch to ASPC after a certain number of exact steps is done
     459           66 :          IF (almo_scf_env%almo_history%istore > (almo_scf_env%almo_history%nstore + 1)) THEN
     460            2 :             IF (almo_scf_env%opt_block_diag_pcg%eps_error_early > 0.0_dp) THEN
     461            0 :                almo_scf_env%opt_block_diag_pcg%eps_error = almo_scf_env%opt_block_diag_pcg%eps_error_early
     462            0 :                almo_scf_env%opt_block_diag_pcg%early_stopping_on = .TRUE.
     463            0 :                IF (unit_nr > 0) WRITE (*, *) "ALMO_OPTIMIZER_PCG: EPS_ERROR_EARLY is on"
     464              :             END IF
     465            2 :             IF (almo_scf_env%opt_block_diag_diis%eps_error_early > 0.0_dp) THEN
     466            0 :                almo_scf_env%opt_block_diag_diis%eps_error = almo_scf_env%opt_block_diag_diis%eps_error_early
     467            0 :                almo_scf_env%opt_block_diag_diis%early_stopping_on = .TRUE.
     468            0 :                IF (unit_nr > 0) WRITE (*, *) "ALMO_OPTIMIZER_DIIS: EPS_ERROR_EARLY is on"
     469              :             END IF
     470            2 :             IF (almo_scf_env%opt_block_diag_pcg%max_iter_early > 0) THEN
     471            0 :                almo_scf_env%opt_block_diag_pcg%max_iter = almo_scf_env%opt_block_diag_pcg%max_iter_early
     472            0 :                almo_scf_env%opt_block_diag_pcg%early_stopping_on = .TRUE.
     473            0 :                IF (unit_nr > 0) WRITE (*, *) "ALMO_OPTIMIZER_PCG: MAX_ITER_EARLY is on"
     474              :             END IF
     475            2 :             IF (almo_scf_env%opt_block_diag_diis%max_iter_early > 0) THEN
     476            0 :                almo_scf_env%opt_block_diag_diis%max_iter = almo_scf_env%opt_block_diag_diis%max_iter_early
     477            0 :                almo_scf_env%opt_block_diag_diis%early_stopping_on = .TRUE.
     478            0 :                IF (unit_nr > 0) WRITE (*, *) "ALMO_OPTIMIZER_DIIS: MAX_ITER_EARLY is on"
     479              :             END IF
     480              :          ELSE
     481           64 :             almo_scf_env%opt_block_diag_diis%early_stopping_on = .FALSE.
     482           64 :             almo_scf_env%opt_block_diag_pcg%early_stopping_on = .FALSE.
     483              :          END IF
     484           66 :          IF (almo_scf_env%xalmo_history%istore > (almo_scf_env%xalmo_history%nstore + 1)) THEN
     485            4 :             IF (almo_scf_env%opt_xalmo_pcg%eps_error_early > 0.0_dp) THEN
     486            0 :                almo_scf_env%opt_xalmo_pcg%eps_error = almo_scf_env%opt_xalmo_pcg%eps_error_early
     487            0 :                almo_scf_env%opt_xalmo_pcg%early_stopping_on = .TRUE.
     488            0 :                IF (unit_nr > 0) WRITE (*, *) "XALMO_OPTIMIZER_PCG: EPS_ERROR_EARLY is on"
     489              :             END IF
     490            4 :             IF (almo_scf_env%opt_xalmo_pcg%max_iter_early > 0.0_dp) THEN
     491            0 :                almo_scf_env%opt_xalmo_pcg%max_iter = almo_scf_env%opt_xalmo_pcg%max_iter_early
     492            0 :                almo_scf_env%opt_xalmo_pcg%early_stopping_on = .TRUE.
     493            0 :                IF (unit_nr > 0) WRITE (*, *) "XALMO_OPTIMIZER_PCG: MAX_ITER_EARLY is on"
     494              :             END IF
     495              :          ELSE
     496           62 :             almo_scf_env%opt_xalmo_pcg%early_stopping_on = .FALSE.
     497              :          END IF
     498              :       END IF
     499              : 
     500              :       ! create all matrices
     501          122 :       CALL almo_scf_env_create_matrices(almo_scf_env, matrix_s(1)%matrix)
     502              : 
     503              :       ! set up matrix S and all required functions of S
     504          122 :       almo_scf_env%s_inv_done = .FALSE.
     505          122 :       almo_scf_env%s_sqrt_done = .FALSE.
     506          122 :       CALL almo_scf_init_ao_overlap(matrix_s(1)%matrix, almo_scf_env)
     507              : 
     508              :       ! create the quencher (imposes sparsity template)
     509          122 :       CALL almo_scf_construct_quencher(qs_env, almo_scf_env)
     510          122 :       CALL distribute_domains(almo_scf_env)
     511              : 
     512              :       ! FINISH setting job parameters here, print out job info
     513          122 :       CALL almo_scf_print_job_info(almo_scf_env, unit_nr)
     514              : 
     515              :       ! allocate and init the domain preconditioner
     516         1450 :       ALLOCATE (almo_scf_env%domain_preconditioner(ndomains, nspins))
     517          122 :       CALL init_submatrices(almo_scf_env%domain_preconditioner)
     518              : 
     519              :       ! allocate and init projected KS for domains
     520         1328 :       ALLOCATE (almo_scf_env%domain_ks_xx(ndomains, nspins))
     521          122 :       CALL init_submatrices(almo_scf_env%domain_ks_xx)
     522              : 
     523              :       ! init ao-overlap subblocks
     524         1328 :       ALLOCATE (almo_scf_env%domain_s_inv(ndomains, nspins))
     525          122 :       CALL init_submatrices(almo_scf_env%domain_s_inv)
     526         1328 :       ALLOCATE (almo_scf_env%domain_s_sqrt_inv(ndomains, nspins))
     527          122 :       CALL init_submatrices(almo_scf_env%domain_s_sqrt_inv)
     528         1328 :       ALLOCATE (almo_scf_env%domain_s_sqrt(ndomains, nspins))
     529          122 :       CALL init_submatrices(almo_scf_env%domain_s_sqrt)
     530         1328 :       ALLOCATE (almo_scf_env%domain_t(ndomains, nspins))
     531          122 :       CALL init_submatrices(almo_scf_env%domain_t)
     532         1328 :       ALLOCATE (almo_scf_env%domain_err(ndomains, nspins))
     533          122 :       CALL init_submatrices(almo_scf_env%domain_err)
     534         1328 :       ALLOCATE (almo_scf_env%domain_r_down_up(ndomains, nspins))
     535          122 :       CALL init_submatrices(almo_scf_env%domain_r_down_up)
     536              : 
     537              :       ! initialization of the KS matrix
     538              :       CALL init_almo_ks_matrix_via_qs(qs_env, &
     539              :                                       almo_scf_env%matrix_ks, &
     540              :                                       almo_scf_env%mat_distr_aos, &
     541          122 :                                       almo_scf_env%eps_filter)
     542          122 :       CALL construct_qs_mos(qs_env, almo_scf_env)
     543              : 
     544          122 :       CALL timestop(handle)
     545              : 
     546          244 :    END SUBROUTINE almo_scf_init
     547              : 
     548              : ! **************************************************************************************************
     549              : !> \brief create the scf initial guess for ALMOs
     550              : !> \param qs_env ...
     551              : !> \param almo_scf_env ...
     552              : !> \par History
     553              : !>       2016.11 created [Rustam Z Khaliullin]
     554              : !>       2018.09 smearing support [Ruben Staub]
     555              : !> \author Rustam Z Khaliullin
     556              : ! **************************************************************************************************
     557          122 :    SUBROUTINE almo_scf_initial_guess(qs_env, almo_scf_env)
     558              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     559              :       TYPE(almo_scf_env_type), INTENT(INOUT)             :: almo_scf_env
     560              : 
     561              :       CHARACTER(len=*), PARAMETER :: routineN = 'almo_scf_initial_guess'
     562              : 
     563              :       CHARACTER(LEN=default_path_length)                 :: file_name, project_name
     564              :       INTEGER                                            :: handle, iaspc, ispin, istore, naspc, &
     565              :                                                             nspins, unit_nr
     566              :       INTEGER, DIMENSION(2)                              :: nelectron_spin
     567              :       LOGICAL                                            :: aspc_guess, has_unit_metric
     568              :       REAL(KIND=dp)                                      :: alpha, cs_pos, energy, kTS_sum
     569          122 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     570              :       TYPE(cp_logger_type), POINTER                      :: logger
     571              :       TYPE(dbcsr_distribution_type)                      :: dist
     572          122 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_s, rho_ao
     573              :       TYPE(dft_control_type), POINTER                    :: dft_control
     574              :       TYPE(molecular_scf_guess_env_type), POINTER        :: mscfg_env
     575              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     576          122 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     577          122 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     578              :       TYPE(qs_rho_type), POINTER                         :: rho
     579              : 
     580          122 :       CALL timeset(routineN, handle)
     581              : 
     582          122 :       NULLIFY (rho, rho_ao)
     583              : 
     584              :       ! get a useful output_unit
     585          122 :       logger => cp_get_default_logger()
     586          122 :       IF (logger%para_env%is_source()) THEN
     587           61 :          unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
     588              :       ELSE
     589           61 :          unit_nr = -1
     590              :       END IF
     591              : 
     592              :       ! get basic quantities from the qs_env
     593              :       CALL get_qs_env(qs_env, &
     594              :                       dft_control=dft_control, &
     595              :                       matrix_s=matrix_s, &
     596              :                       atomic_kind_set=atomic_kind_set, &
     597              :                       qs_kind_set=qs_kind_set, &
     598              :                       particle_set=particle_set, &
     599              :                       has_unit_metric=has_unit_metric, &
     600              :                       para_env=para_env, &
     601              :                       nelectron_spin=nelectron_spin, &
     602              :                       mscfg_env=mscfg_env, &
     603          122 :                       rho=rho)
     604              : 
     605          122 :       CALL qs_rho_get(rho, rho_ao=rho_ao)
     606          122 :       CPASSERT(ASSOCIATED(mscfg_env))
     607              : 
     608              :       ! initial guess on the first simulation step is determined by almo_scf_env%almo_scf_guess
     609              :       ! the subsequent simulation steps are determined by extrapolation_order
     610              :       ! if extrapolation order is zero then again almo_scf_env%almo_scf_guess is used
     611              :       ! ... the number of stored history points will remain zero if extrapolation order is zero
     612          122 :       IF (almo_scf_env%almo_history%istore == 0) THEN
     613              :          aspc_guess = .FALSE.
     614              :       ELSE
     615           46 :          aspc_guess = .TRUE.
     616              :       END IF
     617              : 
     618          122 :       nspins = almo_scf_env%nspins
     619              : 
     620              :       ! create an initial guess
     621          122 :       IF (.NOT. aspc_guess) THEN
     622              : 
     623           92 :          SELECT CASE (almo_scf_env%almo_scf_guess)
     624              :          CASE (molecular_guess)
     625              : 
     626           38 :             DO ispin = 1, nspins
     627              : 
     628              :                ! the calculations on "isolated" molecules has already been done
     629              :                ! all we need to do is convert the MOs of molecules into
     630              :                ! the ALMO matrix taking into account different distributions
     631              :                CALL get_matrix_from_submatrices(mscfg_env, &
     632           22 :                                                 almo_scf_env%matrix_t_blk(ispin), ispin)
     633              :                CALL dbcsr_filter(almo_scf_env%matrix_t_blk(ispin), &
     634           38 :                                  almo_scf_env%eps_filter)
     635              : 
     636              :             END DO
     637              : 
     638              :          CASE (atomic_guess)
     639              : 
     640           60 :             IF (dft_control%qs_control%dftb .OR. dft_control%qs_control%semi_empirical .OR. &
     641              :                 dft_control%qs_control%xtb) THEN
     642              :                CALL calculate_mopac_dm(rho_ao, &
     643              :                                        matrix_s(1)%matrix, has_unit_metric, &
     644              :                                        dft_control, particle_set, atomic_kind_set, qs_kind_set, &
     645              :                                        nspins, nelectron_spin, &
     646            0 :                                        para_env)
     647              :             ELSE
     648              :                CALL calculate_atomic_block_dm(rho_ao, matrix_s(1)%matrix, atomic_kind_set, qs_kind_set, &
     649           60 :                                               nspins, nelectron_spin, unit_nr, para_env)
     650              :             END IF
     651              : 
     652          120 :             DO ispin = 1, nspins
     653              :                ! copy the atomic-block dm into matrix_p_blk
     654              :                CALL matrix_qs_to_almo(rho_ao(ispin)%matrix, &
     655           60 :                                       almo_scf_env%matrix_p_blk(ispin), almo_scf_env%mat_distr_aos)
     656              :                CALL dbcsr_filter(almo_scf_env%matrix_p_blk(ispin), &
     657          120 :                                  almo_scf_env%eps_filter)
     658              :             END DO ! ispin
     659              : 
     660              :             ! obtain orbitals from the density matrix
     661              :             ! (the current version of ALMO SCF needs orbitals)
     662           60 :             CALL almo_scf_p_blk_to_t_blk(almo_scf_env, ionic=.FALSE.)
     663              : 
     664              :          CASE (restart_guess)
     665              : 
     666            0 :             project_name = logger%iter_info%project_name
     667              : 
     668           76 :             DO ispin = 1, nspins
     669            0 :                WRITE (file_name, '(A,I0,A)') TRIM(project_name)//"_ALMO_SPIN_", ispin, "_RESTART.mo"
     670            0 :                CALL dbcsr_get_info(almo_scf_env%matrix_t_blk(ispin), distribution=dist)
     671            0 :                CALL dbcsr_binary_read(file_name, distribution=dist, matrix_new=almo_scf_env%matrix_t_blk(ispin))
     672            0 :                cs_pos = dbcsr_checksum(almo_scf_env%matrix_t_blk(ispin), pos=.TRUE.)
     673            0 :                IF (unit_nr > 0) THEN
     674            0 :                   WRITE (unit_nr, '(T2,A,E20.8)') "Read restart ALMO "//TRIM(file_name)//" with checksum: ", cs_pos
     675              :                END IF
     676              :             END DO
     677              :          END SELECT
     678              : 
     679              :       ELSE !aspc_guess
     680              : 
     681           46 :          CALL cite_reference(Kolafa2004)
     682           46 :          CALL cite_reference(Kuhne2007)
     683              : 
     684           46 :          naspc = MIN(almo_scf_env%almo_history%istore, almo_scf_env%almo_history%nstore)
     685           46 :          IF (unit_nr > 0) THEN
     686              :             WRITE (unit_nr, FMT="(/,T2,A,/,/,T3,A,I0)") &
     687           23 :                "Parameters for the always stable predictor-corrector (ASPC) method:", &
     688           46 :                "ASPC order: ", naspc
     689              :          END IF
     690              : 
     691           92 :          DO ispin = 1, nspins
     692              : 
     693              :             ! extrapolation
     694          186 :             DO iaspc = 1, naspc
     695           94 :                istore = MOD(almo_scf_env%almo_history%istore - iaspc, almo_scf_env%almo_history%nstore) + 1
     696              :                alpha = (-1.0_dp)**(iaspc + 1)*REAL(iaspc, KIND=dp)* &
     697           94 :                        binomial(2*naspc, naspc - iaspc)/binomial(2*naspc - 2, naspc - 1)
     698           94 :                IF (unit_nr > 0) THEN
     699              :                   WRITE (unit_nr, FMT="(T3,A2,I0,A4,F10.6)") &
     700           47 :                      "B(", iaspc, ") = ", alpha
     701              :                END IF
     702          140 :                IF (iaspc == 1) THEN
     703              :                   CALL dbcsr_copy(almo_scf_env%matrix_t_blk(ispin), &
     704              :                                   almo_scf_env%almo_history%matrix_t(ispin), &
     705           46 :                                   keep_sparsity=.TRUE.)
     706           46 :                   CALL dbcsr_scale(almo_scf_env%matrix_t_blk(ispin), alpha)
     707              :                ELSE
     708              :                   CALL dbcsr_multiply("N", "N", alpha, &
     709              :                                       almo_scf_env%almo_history%matrix_p_up_down(ispin, istore), &
     710              :                                       almo_scf_env%almo_history%matrix_t(ispin), &
     711              :                                       1.0_dp, almo_scf_env%matrix_t_blk(ispin), &
     712           48 :                                       retain_sparsity=.TRUE.)
     713              :                END IF
     714              :             END DO !iaspc
     715              : 
     716              :          END DO !ispin
     717              : 
     718              :       END IF !aspc_guess?
     719              : 
     720          250 :       DO ispin = 1, nspins
     721              : 
     722              :          CALL orthogonalize_mos(ket=almo_scf_env%matrix_t_blk(ispin), &
     723              :                                 overlap=almo_scf_env%matrix_sigma_blk(ispin), &
     724              :                                 metric=almo_scf_env%matrix_s_blk(1), &
     725              :                                 retain_locality=.TRUE., &
     726              :                                 only_normalize=.FALSE., &
     727              :                                 nocc_of_domain=almo_scf_env%nocc_of_domain(:, ispin), &
     728              :                                 eps_filter=almo_scf_env%eps_filter, &
     729              :                                 order_lanczos=almo_scf_env%order_lanczos, &
     730              :                                 eps_lanczos=almo_scf_env%eps_lanczos, &
     731          128 :                                 max_iter_lanczos=almo_scf_env%max_iter_lanczos)
     732              : 
     733              :          !! Application of an occupation-rescaling trick for smearing, if requested
     734          128 :          IF (almo_scf_env%smear) THEN
     735              :             CALL almo_scf_t_rescaling(matrix_t=almo_scf_env%matrix_t_blk(ispin), &
     736              :                                       mo_energies=almo_scf_env%mo_energies(:, ispin), &
     737              :                                       mu_of_domain=almo_scf_env%mu_of_domain(:, ispin), &
     738              :                                       real_ne_of_domain=almo_scf_env%real_ne_of_domain(:, ispin), &
     739              :                                       spin_kTS=almo_scf_env%kTS(ispin), &
     740              :                                       smear_e_temp=almo_scf_env%smear_e_temp, &
     741              :                                       ndomains=almo_scf_env%ndomains, &
     742            4 :                                       nocc_of_domain=almo_scf_env%nocc_of_domain(:, ispin))
     743              :          END IF
     744              : 
     745              :          CALL almo_scf_t_to_proj(t=almo_scf_env%matrix_t_blk(ispin), &
     746              :                                  p=almo_scf_env%matrix_p(ispin), &
     747              :                                  eps_filter=almo_scf_env%eps_filter, &
     748              :                                  orthog_orbs=.FALSE., &
     749              :                                  nocc_of_domain=almo_scf_env%nocc_of_domain(:, ispin), &
     750              :                                  s=almo_scf_env%matrix_s(1), &
     751              :                                  sigma=almo_scf_env%matrix_sigma(ispin), &
     752              :                                  sigma_inv=almo_scf_env%matrix_sigma_inv(ispin), &
     753              :                                  use_guess=.FALSE., &
     754              :                                  smear=almo_scf_env%smear, &
     755              :                                  algorithm=almo_scf_env%sigma_inv_algorithm, &
     756              :                                  eps_lanczos=almo_scf_env%eps_lanczos, &
     757              :                                  max_iter_lanczos=almo_scf_env%max_iter_lanczos, &
     758              :                                  inv_eps_factor=almo_scf_env%matrix_iter_eps_error_factor, &
     759              :                                  para_env=almo_scf_env%para_env, &
     760          250 :                                  blacs_env=almo_scf_env%blacs_env)
     761              : 
     762              :       END DO
     763              : 
     764              :       ! compute dm from the projector(s)
     765          122 :       IF (nspins == 1) THEN
     766          116 :          CALL dbcsr_scale(almo_scf_env%matrix_p(1), 2.0_dp)
     767              :          !! Rescaling electronic entropy contribution by spin_factor
     768          116 :          IF (almo_scf_env%smear) THEN
     769            4 :             almo_scf_env%kTS(1) = almo_scf_env%kTS(1)*2.0_dp
     770              :          END IF
     771              :       END IF
     772              : 
     773          122 :       IF (almo_scf_env%smear) THEN
     774            8 :          kTS_sum = SUM(almo_scf_env%kTS)
     775              :       ELSE
     776          118 :          kTS_sum = 0.0_dp
     777              :       END IF
     778              : 
     779              :       CALL almo_dm_to_almo_ks(qs_env, &
     780              :                               almo_scf_env%matrix_p, &
     781              :                               almo_scf_env%matrix_ks, &
     782              :                               energy, &
     783              :                               almo_scf_env%eps_filter, &
     784              :                               almo_scf_env%mat_distr_aos, &
     785              :                               smear=almo_scf_env%smear, &
     786          122 :                               kTS_sum=kTS_sum)
     787              : 
     788          122 :       IF (unit_nr > 0) THEN
     789           61 :          IF (almo_scf_env%almo_scf_guess == molecular_guess) THEN
     790            8 :             WRITE (unit_nr, '(T2,A38,F40.10)') "Single-molecule energy:", &
     791           38 :                SUM(mscfg_env%energy_of_frag)
     792              :          END IF
     793           61 :          WRITE (unit_nr, '(T2,A38,F40.10)') "Energy of the initial guess:", energy
     794           61 :          WRITE (unit_nr, '()')
     795              :       END IF
     796              : 
     797          122 :       CALL timestop(handle)
     798              : 
     799          122 :    END SUBROUTINE almo_scf_initial_guess
     800              : 
     801              : ! **************************************************************************************************
     802              : !> \brief store a history of matrices for later use in almo_scf_initial_guess
     803              : !> \param almo_scf_env ...
     804              : !> \par History
     805              : !>       2016.11 created [Rustam Z Khaliullin]
     806              : !> \author Rustam Khaliullin
     807              : ! **************************************************************************************************
     808          122 :    SUBROUTINE almo_scf_store_extrapolation_data(almo_scf_env)
     809              :       TYPE(almo_scf_env_type), INTENT(INOUT)             :: almo_scf_env
     810              : 
     811              :       CHARACTER(len=*), PARAMETER :: routineN = 'almo_scf_store_extrapolation_data'
     812              : 
     813              :       INTEGER                                            :: handle, ispin, istore, unit_nr
     814              :       LOGICAL :: delocalization_uses_extrapolation
     815              :       TYPE(cp_logger_type), POINTER                      :: logger
     816              :       TYPE(dbcsr_type)                                   :: matrix_no_tmp1, matrix_no_tmp2, &
     817              :                                                             matrix_no_tmp3, matrix_no_tmp4
     818              : 
     819          122 :       CALL timeset(routineN, handle)
     820              : 
     821              :       ! get a useful output_unit
     822          122 :       logger => cp_get_default_logger()
     823          122 :       IF (logger%para_env%is_source()) THEN
     824           61 :          unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
     825              :       ELSE
     826              :          unit_nr = -1
     827              :       END IF
     828              : 
     829          122 :       IF (almo_scf_env%almo_history%nstore > 0) THEN
     830              : 
     831          116 :          almo_scf_env%almo_history%istore = almo_scf_env%almo_history%istore + 1
     832              : 
     833          238 :          DO ispin = 1, SIZE(almo_scf_env%matrix_t_blk)
     834              : 
     835          122 :             istore = MOD(almo_scf_env%almo_history%istore - 1, almo_scf_env%almo_history%nstore) + 1
     836              : 
     837          122 :             IF (almo_scf_env%almo_history%istore == 1) THEN
     838              :                CALL dbcsr_create(almo_scf_env%almo_history%matrix_t(ispin), &
     839              :                                  template=almo_scf_env%matrix_t_blk(ispin), &
     840           76 :                                  matrix_type=dbcsr_type_no_symmetry)
     841              :             END IF
     842              :             CALL dbcsr_copy(almo_scf_env%almo_history%matrix_t(ispin), &
     843          122 :                             almo_scf_env%matrix_t_blk(ispin))
     844              : 
     845          122 :             IF (almo_scf_env%almo_history%istore <= almo_scf_env%almo_history%nstore) THEN
     846              :                CALL dbcsr_create(almo_scf_env%almo_history%matrix_p_up_down(ispin, istore), &
     847              :                                  template=almo_scf_env%matrix_s(1), &
     848          100 :                                  matrix_type=dbcsr_type_no_symmetry)
     849              :             END IF
     850              : 
     851              :             CALL dbcsr_create(matrix_no_tmp1, template=almo_scf_env%matrix_t_blk(ispin), &
     852          122 :                               matrix_type=dbcsr_type_no_symmetry)
     853              :             CALL dbcsr_create(matrix_no_tmp2, template=almo_scf_env%matrix_t_blk(ispin), &
     854          122 :                               matrix_type=dbcsr_type_no_symmetry)
     855              : 
     856              :             ! compute contra-covariant density matrix
     857              :             CALL dbcsr_multiply("N", "N", 1.0_dp, almo_scf_env%matrix_s(1), &
     858              :                                 almo_scf_env%matrix_t_blk(ispin), &
     859              :                                 0.0_dp, matrix_no_tmp1, &
     860          122 :                                 filter_eps=almo_scf_env%eps_filter)
     861              :             CALL dbcsr_multiply("N", "N", 1.0_dp, matrix_no_tmp1, &
     862              :                                 almo_scf_env%matrix_sigma_inv_0deloc(ispin), &
     863              :                                 0.0_dp, matrix_no_tmp2, &
     864          122 :                                 filter_eps=almo_scf_env%eps_filter)
     865              :             CALL dbcsr_multiply("N", "T", 1.0_dp, &
     866              :                                 almo_scf_env%matrix_t_blk(ispin), &
     867              :                                 matrix_no_tmp2, &
     868              :                                 0.0_dp, almo_scf_env%almo_history%matrix_p_up_down(ispin, istore), &
     869          122 :                                 filter_eps=almo_scf_env%eps_filter)
     870              : 
     871          122 :             CALL dbcsr_release(matrix_no_tmp1)
     872          238 :             CALL dbcsr_release(matrix_no_tmp2)
     873              : 
     874              :          END DO
     875              : 
     876              :       END IF
     877              : 
     878              :       ! exrapolate xalmos?
     879              :       delocalization_uses_extrapolation = &
     880              :          .NOT. ((almo_scf_env%deloc_method == almo_deloc_none) .OR. &
     881          122 :                 (almo_scf_env%deloc_method == almo_deloc_xalmo_1diag))
     882          122 :       IF (almo_scf_env%xalmo_history%nstore > 0 .AND. &
     883              :           delocalization_uses_extrapolation) THEN
     884              : 
     885           44 :          almo_scf_env%xalmo_history%istore = almo_scf_env%xalmo_history%istore + 1
     886              : 
     887           88 :          DO ispin = 1, SIZE(almo_scf_env%matrix_t)
     888              : 
     889           44 :             istore = MOD(almo_scf_env%xalmo_history%istore - 1, almo_scf_env%xalmo_history%nstore) + 1
     890              : 
     891           44 :             IF (almo_scf_env%xalmo_history%istore == 1) THEN
     892              :                CALL dbcsr_create(almo_scf_env%xalmo_history%matrix_t(ispin), &
     893              :                                  template=almo_scf_env%matrix_t(ispin), &
     894           10 :                                  matrix_type=dbcsr_type_no_symmetry)
     895              :             END IF
     896              :             CALL dbcsr_copy(almo_scf_env%xalmo_history%matrix_t(ispin), &
     897           44 :                             almo_scf_env%matrix_t(ispin))
     898              : 
     899           44 :             IF (almo_scf_env%xalmo_history%istore <= almo_scf_env%xalmo_history%nstore) THEN
     900              :                !CALL dbcsr_init(almo_scf_env%xalmo_history%matrix_x(ispin, istore))
     901              :                !CALL dbcsr_create(almo_scf_env%xalmo_history%matrix_x(ispin, istore), &
     902              :                !        template=almo_scf_env%matrix_t(ispin), &
     903              :                !        matrix_type=dbcsr_type_no_symmetry)
     904              :                CALL dbcsr_create(almo_scf_env%xalmo_history%matrix_p_up_down(ispin, istore), &
     905              :                                  template=almo_scf_env%matrix_s(1), &
     906           24 :                                  matrix_type=dbcsr_type_no_symmetry)
     907              :             END IF
     908              : 
     909              :             CALL dbcsr_create(matrix_no_tmp3, template=almo_scf_env%matrix_t(ispin), &
     910           44 :                               matrix_type=dbcsr_type_no_symmetry)
     911              :             CALL dbcsr_create(matrix_no_tmp4, template=almo_scf_env%matrix_t(ispin), &
     912           44 :                               matrix_type=dbcsr_type_no_symmetry)
     913              : 
     914              :             ! compute contra-covariant density matrix
     915              :             CALL dbcsr_multiply("N", "N", 1.0_dp, almo_scf_env%matrix_s(1), &
     916              :                                 almo_scf_env%matrix_t(ispin), &
     917              :                                 0.0_dp, matrix_no_tmp3, &
     918           44 :                                 filter_eps=almo_scf_env%eps_filter)
     919              :             CALL dbcsr_multiply("N", "N", 1.0_dp, matrix_no_tmp3, &
     920              :                                 almo_scf_env%matrix_sigma_inv(ispin), &
     921              :                                 0.0_dp, matrix_no_tmp4, &
     922           44 :                                 filter_eps=almo_scf_env%eps_filter)
     923              :             CALL dbcsr_multiply("N", "T", 1.0_dp, &
     924              :                                 almo_scf_env%matrix_t(ispin), &
     925              :                                 matrix_no_tmp4, &
     926              :                                 0.0_dp, almo_scf_env%xalmo_history%matrix_p_up_down(ispin, istore), &
     927           44 :                                 filter_eps=almo_scf_env%eps_filter)
     928              : 
     929              :             ! store the difference between t and t0
     930              :             !CALL dbcsr_copy(almo_scf_env%xalmo_history%matrix_x(ispin, istore),&
     931              :             !        almo_scf_env%matrix_t(ispin))
     932              :             !CALL dbcsr_add(almo_scf_env%xalmo_history%matrix_x(ispin, istore),&
     933              :             !        almo_scf_env%matrix_t_blk(ispin),1.0_dp,-1.0_dp)
     934              : 
     935           44 :             CALL dbcsr_release(matrix_no_tmp3)
     936           88 :             CALL dbcsr_release(matrix_no_tmp4)
     937              : 
     938              :          END DO
     939              : 
     940              :       END IF
     941              : 
     942          122 :       CALL timestop(handle)
     943              : 
     944          122 :    END SUBROUTINE almo_scf_store_extrapolation_data
     945              : 
     946              : ! **************************************************************************************************
     947              : !> \brief Prints out a short summary about the ALMO SCF job
     948              : !> \param almo_scf_env ...
     949              : !> \param unit_nr ...
     950              : !> \par History
     951              : !>       2011.10 created [Rustam Z Khaliullin]
     952              : !> \author Rustam Z Khaliullin
     953              : ! **************************************************************************************************
     954          122 :    SUBROUTINE almo_scf_print_job_info(almo_scf_env, unit_nr)
     955              : 
     956              :       TYPE(almo_scf_env_type), INTENT(INOUT)             :: almo_scf_env
     957              :       INTEGER, INTENT(IN)                                :: unit_nr
     958              : 
     959              :       CHARACTER(len=*), PARAMETER :: routineN = 'almo_scf_print_job_info'
     960              : 
     961              :       CHARACTER(len=13)                                  :: neig_string
     962              :       CHARACTER(len=33)                                  :: deloc_method_string
     963              :       INTEGER                                            :: handle, idomain, index1_prev, sum_temp
     964          122 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: nneighbors
     965              : 
     966          122 :       CALL timeset(routineN, handle)
     967              : 
     968          122 :       IF (unit_nr > 0) THEN
     969           61 :          WRITE (unit_nr, '()')
     970           61 :          WRITE (unit_nr, '(T2,A,A,A)') REPEAT("-", 32), " ALMO SETTINGS ", REPEAT("-", 32)
     971              : 
     972           61 :          WRITE (unit_nr, '(T2,A,T48,E33.3)') "eps_filter:", almo_scf_env%eps_filter
     973              : 
     974           61 :          IF (almo_scf_env%almo_update_algorithm == almo_scf_skip) THEN
     975           17 :             WRITE (unit_nr, '(T2,A)') "skip optimization of block-diagonal ALMOs"
     976              :          ELSE
     977           44 :             WRITE (unit_nr, '(T2,A)') "optimization of block-diagonal ALMOs:"
     978           82 :             SELECT CASE (almo_scf_env%almo_update_algorithm)
     979              :             CASE (almo_scf_diag)
     980              :                ! the DIIS algorith is the only choice for the diagonlaization-based algorithm
     981           38 :                CALL print_optimizer_options(almo_scf_env%opt_block_diag_diis, unit_nr)
     982              :             CASE (almo_scf_pcg)
     983              :                ! print out PCG options
     984            5 :                CALL print_optimizer_options(almo_scf_env%opt_block_diag_pcg, unit_nr)
     985              :             CASE (almo_scf_trustr)
     986              :                ! print out TRUST REGION options
     987           44 :                CALL print_optimizer_options(almo_scf_env%opt_block_diag_trustr, unit_nr)
     988              :             END SELECT
     989              :          END IF
     990              : 
     991           79 :          SELECT CASE (almo_scf_env%deloc_method)
     992              :          CASE (almo_deloc_none)
     993           18 :             deloc_method_string = "NONE"
     994              :          CASE (almo_deloc_x)
     995            2 :             deloc_method_string = "FULL_X"
     996              :          CASE (almo_deloc_scf)
     997            6 :             deloc_method_string = "FULL_SCF"
     998              :          CASE (almo_deloc_x_then_scf)
     999            7 :             deloc_method_string = "FULL_X_THEN_SCF"
    1000              :          CASE (almo_deloc_xalmo_1diag)
    1001            1 :             deloc_method_string = "XALMO_1DIAG"
    1002              :          CASE (almo_deloc_xalmo_x)
    1003            3 :             deloc_method_string = "XALMO_X"
    1004              :          CASE (almo_deloc_xalmo_scf)
    1005           61 :             deloc_method_string = "XALMO_SCF"
    1006              :          END SELECT
    1007           61 :          WRITE (unit_nr, '(T2,A,T48,A33)') "delocalization:", TRIM(deloc_method_string)
    1008              : 
    1009           61 :          IF (almo_scf_env%deloc_method /= almo_deloc_none) THEN
    1010              : 
    1011           15 :             SELECT CASE (almo_scf_env%deloc_method)
    1012              :             CASE (almo_deloc_x, almo_deloc_scf, almo_deloc_x_then_scf)
    1013           15 :                WRITE (unit_nr, '(T2,A,T48,A33)') "delocalization cutoff radius:", &
    1014           30 :                   "infinite"
    1015           15 :                deloc_method_string = "FULL_X_THEN_SCF"
    1016              :             CASE (almo_deloc_xalmo_1diag, almo_deloc_xalmo_x, almo_deloc_xalmo_scf)
    1017           28 :                WRITE (unit_nr, '(T2,A,T48,F33.5)') "XALMO cutoff radius:", &
    1018           71 :                   almo_scf_env%quencher_r0_factor
    1019              :             END SELECT
    1020              : 
    1021           43 :             IF (almo_scf_env%deloc_method == almo_deloc_xalmo_1diag) THEN
    1022              :                ! print nothing because no actual optimization is done
    1023              :             ELSE
    1024           42 :                WRITE (unit_nr, '(T2,A)') "optimization of extended orbitals:"
    1025           42 :                SELECT CASE (almo_scf_env%xalmo_update_algorithm)
    1026              :                CASE (almo_scf_diag)
    1027            0 :                   CALL print_optimizer_options(almo_scf_env%opt_xalmo_diis, unit_nr)
    1028              :                CASE (almo_scf_trustr)
    1029            8 :                   CALL print_optimizer_options(almo_scf_env%opt_xalmo_trustr, unit_nr)
    1030              :                CASE (almo_scf_pcg)
    1031           42 :                   CALL print_optimizer_options(almo_scf_env%opt_xalmo_pcg, unit_nr)
    1032              :                END SELECT
    1033              :             END IF
    1034              : 
    1035              :          END IF
    1036              : 
    1037              :          !SELECT CASE(almo_scf_env%domain_layout_mos)
    1038              :          !CASE(almo_domain_layout_orbital)
    1039              :          !    WRITE(unit_nr,'(T2,A,T48,A33)') "Delocalization constraints","ORBITAL"
    1040              :          !CASE(almo_domain_layout_atomic)
    1041              :          !    WRITE(unit_nr,'(T2,A,T48,A33)') "Delocalization constraints","ATOMIC"
    1042              :          !CASE(almo_domain_layout_molecular)
    1043              :          !    WRITE(unit_nr,'(T2,A,T48,A33)') "Delocalization constraints","MOLECULAR"
    1044              :          !END SELECT
    1045              : 
    1046              :          !SELECT CASE(almo_scf_env%domain_layout_aos)
    1047              :          !CASE(almo_domain_layout_atomic)
    1048              :          !    WRITE(unit_nr,'(T2,A,T48,A33)') "Basis function domains","ATOMIC"
    1049              :          !CASE(almo_domain_layout_molecular)
    1050              :          !    WRITE(unit_nr,'(T2,A,T48,A33)') "Basis function domains","MOLECULAR"
    1051              :          !END SELECT
    1052              : 
    1053              :          !SELECT CASE(almo_scf_env%mat_distr_aos)
    1054              :          !CASE(almo_mat_distr_atomic)
    1055              :          !    WRITE(unit_nr,'(T2,A,T48,A33)') "Parallel distribution for AOs","ATOMIC"
    1056              :          !CASE(almo_mat_distr_molecular)
    1057              :          !    WRITE(unit_nr,'(T2,A,T48,A33)') "Parallel distribution for AOs","MOLECULAR"
    1058              :          !END SELECT
    1059              : 
    1060              :          !SELECT CASE(almo_scf_env%mat_distr_mos)
    1061              :          !CASE(almo_mat_distr_atomic)
    1062              :          !    WRITE(unit_nr,'(T2,A,T48,A33)') "Parallel distribution for MOs","ATOMIC"
    1063              :          !CASE(almo_mat_distr_molecular)
    1064              :          !    WRITE(unit_nr,'(T2,A,T48,A33)') "Parallel distribution for MOs","MOLECULAR"
    1065              :          !END SELECT
    1066              : 
    1067              :          ! print fragment's statistics
    1068           61 :          WRITE (unit_nr, '(T2,A)') REPEAT("-", 79)
    1069           61 :          WRITE (unit_nr, '(T2,A,T48,I33)') "Total fragments:", &
    1070          122 :             almo_scf_env%ndomains
    1071              : 
    1072          472 :          sum_temp = SUM(almo_scf_env%nbasis_of_domain(:))
    1073              :          WRITE (unit_nr, '(T2,A,T53,I5,F9.2,I5,I9)') &
    1074           61 :             "Basis set size per fragment (min, av, max, total):", &
    1075          472 :             MINVAL(almo_scf_env%nbasis_of_domain(:)), &
    1076           61 :             (1.0_dp*sum_temp)/almo_scf_env%ndomains, &
    1077          472 :             MAXVAL(almo_scf_env%nbasis_of_domain(:)), &
    1078          122 :             sum_temp
    1079              :          !WRITE (unit_nr, '(T2,I13,F13.3,I13,I13)') &
    1080              :          !         MINVAL(almo_scf_env%nbasis_of_domain(:)), &
    1081              :          !         (1.0_dp*sum_temp) / almo_scf_env%ndomains, &
    1082              :          !         MAXVAL(almo_scf_env%nbasis_of_domain(:)), &
    1083              :          !         sum_temp
    1084              : 
    1085          542 :          sum_temp = SUM(almo_scf_env%nocc_of_domain(:, :))
    1086              :          WRITE (unit_nr, '(T2,A,T53,I5,F9.2,I5,I9)') &
    1087           61 :             "Occupied MOs per fragment (min, av, max, total):", &
    1088          889 :             MINVAL(SUM(almo_scf_env%nocc_of_domain, DIM=2)), &
    1089           61 :             (1.0_dp*sum_temp)/almo_scf_env%ndomains, &
    1090          889 :             MAXVAL(SUM(almo_scf_env%nocc_of_domain, DIM=2)), &
    1091          122 :             sum_temp
    1092              :          !WRITE (unit_nr, '(T2,I13,F13.3,I13,I13)') &
    1093              :          !         MINVAL( SUM(almo_scf_env%nocc_of_domain, DIM=2) ), &
    1094              :          !         (1.0_dp*sum_temp) / almo_scf_env%ndomains, &
    1095              :          !         MAXVAL( SUM(almo_scf_env%nocc_of_domain, DIM=2) ), &
    1096              :          !         sum_temp
    1097              : 
    1098          542 :          sum_temp = SUM(almo_scf_env%nvirt_of_domain(:, :))
    1099              :          WRITE (unit_nr, '(T2,A,T53,I5,F9.2,I5,I9)') &
    1100           61 :             "Virtual MOs per fragment (min, av, max, total):", &
    1101          889 :             MINVAL(SUM(almo_scf_env%nvirt_of_domain, DIM=2)), &
    1102           61 :             (1.0_dp*sum_temp)/almo_scf_env%ndomains, &
    1103          889 :             MAXVAL(SUM(almo_scf_env%nvirt_of_domain, DIM=2)), &
    1104          122 :             sum_temp
    1105              :          !WRITE (unit_nr, '(T2,I13,F13.3,I13,I13)') &
    1106              :          !         MINVAL( SUM(almo_scf_env%nvirt_of_domain, DIM=2) ), &
    1107              :          !         (1.0_dp*sum_temp) / almo_scf_env%ndomains, &
    1108              :          !         MAXVAL( SUM(almo_scf_env%nvirt_of_domain, DIM=2) ), &
    1109              :          !         sum_temp
    1110              : 
    1111          472 :          sum_temp = SUM(almo_scf_env%charge_of_domain(:))
    1112              :          WRITE (unit_nr, '(T2,A,T53,I5,F9.2,I5,I9)') &
    1113           61 :             "Charges per fragment (min, av, max, total):", &
    1114          472 :             MINVAL(almo_scf_env%charge_of_domain(:)), &
    1115           61 :             (1.0_dp*sum_temp)/almo_scf_env%ndomains, &
    1116          472 :             MAXVAL(almo_scf_env%charge_of_domain(:)), &
    1117          122 :             sum_temp
    1118              :          !WRITE (unit_nr, '(T2,I13,F13.3,I13,I13)') &
    1119              :          !         MINVAL(almo_scf_env%charge_of_domain(:)), &
    1120              :          !         (1.0_dp*sum_temp) / almo_scf_env%ndomains, &
    1121              :          !         MAXVAL(almo_scf_env%charge_of_domain(:)), &
    1122              :          !         sum_temp
    1123              : 
    1124              :          ! compute the number of neighbors of each fragment
    1125          183 :          ALLOCATE (nneighbors(almo_scf_env%ndomains))
    1126              : 
    1127          472 :          DO idomain = 1, almo_scf_env%ndomains
    1128              : 
    1129          411 :             IF (idomain == 1) THEN
    1130              :                index1_prev = 1
    1131              :             ELSE
    1132          350 :                index1_prev = almo_scf_env%domain_map(1)%index1(idomain - 1)
    1133              :             END IF
    1134              : 
    1135           61 :             SELECT CASE (almo_scf_env%deloc_method)
    1136              :             CASE (almo_deloc_none)
    1137          114 :                nneighbors(idomain) = 0
    1138              :             CASE (almo_deloc_x, almo_deloc_scf, almo_deloc_x_then_scf)
    1139          113 :                nneighbors(idomain) = almo_scf_env%ndomains - 1 ! minus self
    1140              :             CASE (almo_deloc_xalmo_1diag, almo_deloc_xalmo_x, almo_deloc_xalmo_scf)
    1141          184 :                nneighbors(idomain) = almo_scf_env%domain_map(1)%index1(idomain) - index1_prev - 1 ! minus self
    1142              :             CASE DEFAULT
    1143          411 :                nneighbors(idomain) = -1
    1144              :             END SELECT
    1145              : 
    1146              :          END DO ! cycle over domains
    1147              : 
    1148          472 :          sum_temp = SUM(nneighbors(:))
    1149              :          WRITE (unit_nr, '(T2,A,T53,I5,F9.2,I5,I9)') &
    1150           61 :             "Deloc. neighbors of fragment (min, av, max, total):", &
    1151          472 :             MINVAL(nneighbors(:)), &
    1152           61 :             (1.0_dp*sum_temp)/almo_scf_env%ndomains, &
    1153          472 :             MAXVAL(nneighbors(:)), &
    1154          122 :             sum_temp
    1155              : 
    1156           61 :          WRITE (unit_nr, '(T2,A)') REPEAT("-", 79)
    1157           61 :          WRITE (unit_nr, '()')
    1158              : 
    1159           61 :          IF (almo_scf_env%ndomains <= 64) THEN
    1160              : 
    1161              :             ! print fragment info
    1162              :             WRITE (unit_nr, '(T2,A10,A13,A13,A13,A13,A13)') &
    1163           61 :                "Fragment", "Basis Set", "Occupied", "Virtual", "Charge", "Deloc Neig" !,"Discarded Virt"
    1164           61 :             WRITE (unit_nr, '(T2,A)') REPEAT("-", 79)
    1165          472 :             DO idomain = 1, almo_scf_env%ndomains
    1166              : 
    1167          525 :                SELECT CASE (almo_scf_env%deloc_method)
    1168              :                CASE (almo_deloc_none)
    1169          114 :                   neig_string = "NONE"
    1170              :                CASE (almo_deloc_x, almo_deloc_scf, almo_deloc_x_then_scf)
    1171          113 :                   neig_string = "ALL"
    1172              :                CASE (almo_deloc_xalmo_1diag, almo_deloc_xalmo_x, almo_deloc_xalmo_scf)
    1173          184 :                   WRITE (neig_string, '(I13)') nneighbors(idomain)
    1174              :                CASE DEFAULT
    1175          411 :                   neig_string = "N/A"
    1176              :                END SELECT
    1177              : 
    1178              :                WRITE (unit_nr, '(T2,I10,I13,I13,I13,I13,A13)') &
    1179          411 :                   idomain, almo_scf_env%nbasis_of_domain(idomain), &
    1180          828 :                   SUM(almo_scf_env%nocc_of_domain(idomain, :)), &
    1181          828 :                   SUM(almo_scf_env%nvirt_of_domain(idomain, :)), &
    1182              :                   !SUM(almo_scf_env%nvirt_disc_of_domain(idomain,:)),&
    1183          411 :                   almo_scf_env%charge_of_domain(idomain), &
    1184          883 :                   ADJUSTR(TRIM(neig_string))
    1185              : 
    1186              :             END DO ! cycle over domains
    1187              : 
    1188           89 :             SELECT CASE (almo_scf_env%deloc_method)
    1189              :             CASE (almo_deloc_xalmo_1diag, almo_deloc_xalmo_x, almo_deloc_xalmo_scf)
    1190              : 
    1191           28 :                WRITE (unit_nr, '(T2,A)') REPEAT("-", 79)
    1192              : 
    1193              :                ! print fragment neighbors
    1194              :                WRITE (unit_nr, '(T2,A78)') &
    1195           28 :                   "Neighbor lists (including self)"
    1196           28 :                WRITE (unit_nr, '(T2,A)') REPEAT("-", 79)
    1197          273 :                DO idomain = 1, almo_scf_env%ndomains
    1198              : 
    1199          184 :                   IF (idomain == 1) THEN
    1200              :                      index1_prev = 1
    1201              :                   ELSE
    1202          156 :                      index1_prev = almo_scf_env%domain_map(1)%index1(idomain - 1)
    1203              :                   END IF
    1204              : 
    1205          184 :                   WRITE (unit_nr, '(T2,I10,":")') idomain
    1206              :                   WRITE (unit_nr, '(T12,11I6)') &
    1207              :                      almo_scf_env%domain_map(1)%pairs &
    1208         1046 :                      (index1_prev:almo_scf_env%domain_map(1)%index1(idomain) - 1, 1) ! includes self
    1209              : 
    1210              :                END DO ! cycle over domains
    1211              : 
    1212              :             END SELECT
    1213              : 
    1214              :          ELSE ! too big to print details for each fragment
    1215              : 
    1216            0 :             WRITE (unit_nr, '(T2,A)') "The system is too big to print details for each fragment."
    1217              : 
    1218              :          END IF ! how many fragments?
    1219              : 
    1220           61 :          WRITE (unit_nr, '(T2,A)') REPEAT("-", 79)
    1221              : 
    1222           61 :          WRITE (unit_nr, '()')
    1223              : 
    1224           61 :          DEALLOCATE (nneighbors)
    1225              : 
    1226              :       END IF ! unit_nr > 0
    1227              : 
    1228          122 :       CALL timestop(handle)
    1229              : 
    1230          122 :    END SUBROUTINE almo_scf_print_job_info
    1231              : 
    1232              : ! **************************************************************************************************
    1233              : !> \brief Initializes the ALMO SCF copy of the AO overlap matrix
    1234              : !>        and all necessary functions (sqrt, inverse...)
    1235              : !> \param matrix_s ...
    1236              : !> \param almo_scf_env ...
    1237              : !> \par History
    1238              : !>       2011.06 created [Rustam Z Khaliullin]
    1239              : !> \author Rustam Z Khaliullin
    1240              : ! **************************************************************************************************
    1241          122 :    SUBROUTINE almo_scf_init_ao_overlap(matrix_s, almo_scf_env)
    1242              :       TYPE(dbcsr_type), INTENT(IN)                       :: matrix_s
    1243              :       TYPE(almo_scf_env_type), INTENT(INOUT)             :: almo_scf_env
    1244              : 
    1245              :       CHARACTER(len=*), PARAMETER :: routineN = 'almo_scf_init_ao_overlap'
    1246              : 
    1247              :       INTEGER                                            :: handle, unit_nr
    1248              :       TYPE(cp_logger_type), POINTER                      :: logger
    1249              : 
    1250          122 :       CALL timeset(routineN, handle)
    1251              : 
    1252              :       ! get a useful output_unit
    1253          122 :       logger => cp_get_default_logger()
    1254          122 :       IF (logger%para_env%is_source()) THEN
    1255           61 :          unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
    1256              :       ELSE
    1257              :          unit_nr = -1
    1258              :       END IF
    1259              : 
    1260              :       ! make almo copy of S
    1261              :       ! also copy S to S_blk (i.e. to S with the domain structure imposed)
    1262          122 :       IF (almo_scf_env%orthogonal_basis) THEN
    1263            0 :          CALL dbcsr_set(almo_scf_env%matrix_s(1), 0.0_dp)
    1264            0 :          CALL dbcsr_add_on_diag(almo_scf_env%matrix_s(1), 1.0_dp)
    1265            0 :          CALL dbcsr_set(almo_scf_env%matrix_s_blk(1), 0.0_dp)
    1266            0 :          CALL dbcsr_add_on_diag(almo_scf_env%matrix_s_blk(1), 1.0_dp)
    1267              :       ELSE
    1268          122 :          CALL matrix_qs_to_almo(matrix_s, almo_scf_env%matrix_s(1), almo_scf_env%mat_distr_aos)
    1269              :          CALL dbcsr_copy(almo_scf_env%matrix_s_blk(1), &
    1270          122 :                          almo_scf_env%matrix_s(1), keep_sparsity=.TRUE.)
    1271              :       END IF
    1272              : 
    1273          122 :       CALL dbcsr_filter(almo_scf_env%matrix_s(1), almo_scf_env%eps_filter)
    1274          122 :       CALL dbcsr_filter(almo_scf_env%matrix_s_blk(1), almo_scf_env%eps_filter)
    1275              : 
    1276          122 :       IF (almo_scf_env%almo_update_algorithm == almo_scf_diag) THEN
    1277              :          CALL matrix_sqrt_Newton_Schulz(almo_scf_env%matrix_s_blk_sqrt(1), &
    1278              :                                         almo_scf_env%matrix_s_blk_sqrt_inv(1), &
    1279              :                                         almo_scf_env%matrix_s_blk(1), &
    1280              :                                         threshold=almo_scf_env%eps_filter, &
    1281              :                                         order=almo_scf_env%order_lanczos, &
    1282              :                                         !order=0, &
    1283              :                                         eps_lanczos=almo_scf_env%eps_lanczos, &
    1284           76 :                                         max_iter_lanczos=almo_scf_env%max_iter_lanczos)
    1285           46 :       ELSE IF (almo_scf_env%almo_update_algorithm == almo_scf_dm_sign) THEN
    1286              :          CALL invert_Hotelling(almo_scf_env%matrix_s_blk_inv(1), &
    1287              :                                almo_scf_env%matrix_s_blk(1), &
    1288              :                                threshold=almo_scf_env%eps_filter, &
    1289            0 :                                filter_eps=almo_scf_env%eps_filter)
    1290              :       END IF
    1291              : 
    1292          122 :       CALL timestop(handle)
    1293              : 
    1294          122 :    END SUBROUTINE almo_scf_init_ao_overlap
    1295              : 
    1296              : ! **************************************************************************************************
    1297              : !> \brief Selects the subroutine for the optimization of block-daigonal ALMOs.
    1298              : !>        Keep it short and clean.
    1299              : !> \param qs_env ...
    1300              : !> \param almo_scf_env ...
    1301              : !> \par History
    1302              : !>       2011.11 created [Rustam Z Khaliullin]
    1303              : !> \author Rustam Z Khaliullin
    1304              : ! **************************************************************************************************
    1305          122 :    SUBROUTINE almo_scf_main(qs_env, almo_scf_env)
    1306              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1307              :       TYPE(almo_scf_env_type), INTENT(INOUT)             :: almo_scf_env
    1308              : 
    1309              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'almo_scf_main'
    1310              : 
    1311              :       INTEGER                                            :: handle, ispin, unit_nr
    1312              :       TYPE(cp_logger_type), POINTER                      :: logger
    1313              : 
    1314          122 :       CALL timeset(routineN, handle)
    1315              : 
    1316              :       ! get a useful output_unit
    1317          122 :       logger => cp_get_default_logger()
    1318          122 :       IF (logger%para_env%is_source()) THEN
    1319           61 :          unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
    1320              :       ELSE
    1321              :          unit_nr = -1
    1322              :       END IF
    1323              : 
    1324          168 :       SELECT CASE (almo_scf_env%almo_update_algorithm)
    1325              :       CASE (almo_scf_pcg, almo_scf_trustr, almo_scf_skip)
    1326              : 
    1327           10 :          SELECT CASE (almo_scf_env%almo_update_algorithm)
    1328              :          CASE (almo_scf_pcg)
    1329              : 
    1330              :             ! ALMO PCG optimizer as a special case of XALMO PCG
    1331              :             CALL almo_scf_xalmo_pcg(qs_env=qs_env, &
    1332              :                                     almo_scf_env=almo_scf_env, &
    1333              :                                     optimizer=almo_scf_env%opt_block_diag_pcg, &
    1334              :                                     quench_t=almo_scf_env%quench_t_blk, &
    1335              :                                     matrix_t_in=almo_scf_env%matrix_t_blk, &
    1336              :                                     matrix_t_out=almo_scf_env%matrix_t_blk, &
    1337              :                                     assume_t0_q0x=.FALSE., &
    1338              :                                     perturbation_only=.FALSE., &
    1339           10 :                                     special_case=xalmo_case_block_diag)
    1340              : 
    1341              :          CASE (almo_scf_trustr)
    1342              : 
    1343              :             CALL almo_scf_xalmo_trustr(qs_env=qs_env, &
    1344              :                                        almo_scf_env=almo_scf_env, &
    1345              :                                        optimizer=almo_scf_env%opt_block_diag_trustr, &
    1346              :                                        quench_t=almo_scf_env%quench_t_blk, &
    1347              :                                        matrix_t_in=almo_scf_env%matrix_t_blk, &
    1348              :                                        matrix_t_out=almo_scf_env%matrix_t_blk, &
    1349              :                                        perturbation_only=.FALSE., &
    1350           46 :                                        special_case=xalmo_case_block_diag)
    1351              : 
    1352              :          END SELECT
    1353              : 
    1354           98 :          DO ispin = 1, almo_scf_env%nspins
    1355              :             CALL orthogonalize_mos(ket=almo_scf_env%matrix_t_blk(ispin), &
    1356              :                                    overlap=almo_scf_env%matrix_sigma_blk(ispin), &
    1357              :                                    metric=almo_scf_env%matrix_s_blk(1), &
    1358              :                                    retain_locality=.TRUE., &
    1359              :                                    only_normalize=.FALSE., &
    1360              :                                    nocc_of_domain=almo_scf_env%nocc_of_domain(:, ispin), &
    1361              :                                    eps_filter=almo_scf_env%eps_filter, &
    1362              :                                    order_lanczos=almo_scf_env%order_lanczos, &
    1363              :                                    eps_lanczos=almo_scf_env%eps_lanczos, &
    1364           98 :                                    max_iter_lanczos=almo_scf_env%max_iter_lanczos)
    1365              :          END DO
    1366              : 
    1367              :       CASE (almo_scf_diag)
    1368              : 
    1369              :          ! mixing/DIIS optimizer
    1370              :          CALL almo_scf_block_diagonal(qs_env, almo_scf_env, &
    1371          122 :                                       almo_scf_env%opt_block_diag_diis)
    1372              : 
    1373              :       END SELECT
    1374              : 
    1375              :       ! we might need a copy of the converged KS and sigma_inv
    1376          250 :       DO ispin = 1, almo_scf_env%nspins
    1377              :          CALL dbcsr_copy(almo_scf_env%matrix_ks_0deloc(ispin), &
    1378          128 :                          almo_scf_env%matrix_ks(ispin))
    1379              :          CALL dbcsr_copy(almo_scf_env%matrix_sigma_inv_0deloc(ispin), &
    1380          250 :                          almo_scf_env%matrix_sigma_inv(ispin))
    1381              :       END DO
    1382              : 
    1383          122 :       CALL timestop(handle)
    1384              : 
    1385          122 :    END SUBROUTINE almo_scf_main
    1386              : 
    1387              : ! **************************************************************************************************
    1388              : !> \brief selects various post scf routines
    1389              : !> \param qs_env ...
    1390              : !> \param almo_scf_env ...
    1391              : !> \par History
    1392              : !>       2011.06 created [Rustam Z Khaliullin]
    1393              : !> \author Rustam Z Khaliullin
    1394              : ! **************************************************************************************************
    1395          122 :    SUBROUTINE almo_scf_delocalization(qs_env, almo_scf_env)
    1396              : 
    1397              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1398              :       TYPE(almo_scf_env_type), INTENT(INOUT)             :: almo_scf_env
    1399              : 
    1400              :       CHARACTER(len=*), PARAMETER :: routineN = 'almo_scf_delocalization'
    1401              : 
    1402              :       INTEGER                                            :: handle, ispin, unit_nr
    1403              :       LOGICAL                                            :: almo_experimental
    1404              :       TYPE(cp_logger_type), POINTER                      :: logger
    1405          122 :       TYPE(dbcsr_type), ALLOCATABLE, DIMENSION(:)        :: no_quench
    1406              :       TYPE(optimizer_options_type)                       :: arbitrary_optimizer
    1407              : 
    1408          122 :       CALL timeset(routineN, handle)
    1409              : 
    1410              :       ! get a useful output_unit
    1411          122 :       logger => cp_get_default_logger()
    1412          122 :       IF (logger%para_env%is_source()) THEN
    1413           61 :          unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
    1414              :       ELSE
    1415              :          unit_nr = -1
    1416              :       END IF
    1417              : 
    1418              :       ! create a local optimizer that handles XALMO DIIS
    1419              :       ! the options of this optimizer are arbitrary because
    1420              :       ! XALMO DIIS SCF does not converge for yet unknown reasons and
    1421              :       ! currently used in the code to get perturbative estimates only
    1422          122 :       arbitrary_optimizer%optimizer_type = optimizer_diis
    1423          122 :       arbitrary_optimizer%max_iter = 3
    1424          122 :       arbitrary_optimizer%eps_error = 1.0E-6_dp
    1425          122 :       arbitrary_optimizer%ndiis = 2
    1426              : 
    1427          152 :       SELECT CASE (almo_scf_env%deloc_method)
    1428              :       CASE (almo_deloc_x, almo_deloc_scf, almo_deloc_x_then_scf)
    1429              : 
    1430              :          ! RZK-warning hack into the quenched routine:
    1431              :          ! create a quench matrix with all-all-all blocks 1.0
    1432              :          ! it is a waste of memory but since matrices are distributed
    1433              :          ! we can tolerate it for now
    1434          120 :          ALLOCATE (no_quench(almo_scf_env%nspins))
    1435              :          CALL dbcsr_create(no_quench(1), &
    1436              :                            template=almo_scf_env%matrix_t(1), &
    1437           30 :                            matrix_type=dbcsr_type_no_symmetry)
    1438           30 :          CALL dbcsr_reserve_all_blocks(no_quench(1))
    1439           30 :          CALL dbcsr_set(no_quench(1), 1.0_dp)
    1440          152 :          IF (almo_scf_env%nspins > 1) THEN
    1441            0 :             DO ispin = 2, almo_scf_env%nspins
    1442              :                CALL dbcsr_create(no_quench(ispin), &
    1443              :                                  template=almo_scf_env%matrix_t(1), &
    1444            0 :                                  matrix_type=dbcsr_type_no_symmetry)
    1445            0 :                CALL dbcsr_copy(no_quench(ispin), no_quench(1))
    1446              :             END DO
    1447              :          END IF
    1448              : 
    1449              :       END SELECT
    1450              : 
    1451          170 :       SELECT CASE (almo_scf_env%deloc_method)
    1452              :       CASE (almo_deloc_none, almo_deloc_scf)
    1453              : 
    1454          102 :          DO ispin = 1, almo_scf_env%nspins
    1455              :             CALL dbcsr_copy(almo_scf_env%matrix_t(ispin), &
    1456          102 :                             almo_scf_env%matrix_t_blk(ispin))
    1457              :          END DO
    1458              : 
    1459              :       CASE (almo_deloc_x, almo_deloc_xk, almo_deloc_x_then_scf)
    1460              : 
    1461              :          !!!! RZK-warning a whole class of delocalization methods
    1462              :          !!!! are commented out at the moment because some of their
    1463              :          !!!! routines have not been thoroughly tested.
    1464              : 
    1465              :          !!!! if we have virtuals pre-optimize and truncate them
    1466              :          !!!IF (almo_scf_env%need_virtuals) THEN
    1467              :          !!!   SELECT CASE (almo_scf_env%deloc_truncate_virt)
    1468              :          !!!   CASE (virt_full)
    1469              :          !!!      ! simply copy virtual orbitals from matrix_v_full_blk to matrix_v_blk
    1470              :          !!!      DO ispin=1,almo_scf_env%nspins
    1471              :          !!!         CALL dbcsr_copy(almo_scf_env%matrix_v_blk(ispin),&
    1472              :          !!!                 almo_scf_env%matrix_v_full_blk(ispin))
    1473              :          !!!      ENDDO
    1474              :          !!!   CASE (virt_number,virt_occ_size)
    1475              :          !!!      CALL split_v_blk(almo_scf_env)
    1476              :          !!!      !CALL truncate_subspace_v_blk(qs_env,almo_scf_env)
    1477              :          !!!   CASE DEFAULT
    1478              :          !!!      CPErrorMessage(cp_failure_level,routineP,"illegal method for virtual space truncation")
    1479              :          !!!      CPPrecondition(.FALSE.,cp_failure_level,routineP,failure)
    1480              :          !!!   END SELECT
    1481              :          !!!ENDIF
    1482              :          !!!CALL harris_foulkes_correction(qs_env,almo_scf_env)
    1483              : 
    1484           18 :          IF (almo_scf_env%xalmo_update_algorithm == almo_scf_pcg) THEN
    1485              : 
    1486              :             CALL almo_scf_xalmo_pcg(qs_env=qs_env, &
    1487              :                                     almo_scf_env=almo_scf_env, &
    1488              :                                     optimizer=almo_scf_env%opt_xalmo_pcg, &
    1489              :                                     quench_t=no_quench, &
    1490              :                                     matrix_t_in=almo_scf_env%matrix_t_blk, &
    1491              :                                     matrix_t_out=almo_scf_env%matrix_t, &
    1492              :                                     assume_t0_q0x=(almo_scf_env%xalmo_trial_wf == xalmo_trial_r0_out), &
    1493              :                                     perturbation_only=.TRUE., &
    1494           18 :                                     special_case=xalmo_case_fully_deloc)
    1495              : 
    1496            0 :          ELSE IF (almo_scf_env%xalmo_update_algorithm == almo_scf_trustr) THEN
    1497              : 
    1498              :             CALL almo_scf_xalmo_trustr(qs_env=qs_env, &
    1499              :                                        almo_scf_env=almo_scf_env, &
    1500              :                                        optimizer=almo_scf_env%opt_xalmo_trustr, &
    1501              :                                        quench_t=no_quench, &
    1502              :                                        matrix_t_in=almo_scf_env%matrix_t_blk, &
    1503              :                                        matrix_t_out=almo_scf_env%matrix_t, &
    1504              :                                        perturbation_only=.TRUE., &
    1505            0 :                                        special_case=xalmo_case_fully_deloc)
    1506              : 
    1507              :          ELSE
    1508              : 
    1509            0 :             CPABORT("Other algorithms do not exist")
    1510              : 
    1511              :          END IF
    1512              : 
    1513              :       CASE (almo_deloc_xalmo_1diag)
    1514              : 
    1515            2 :          IF (almo_scf_env%xalmo_update_algorithm == almo_scf_diag) THEN
    1516              : 
    1517            2 :             almo_scf_env%perturbative_delocalization = .TRUE.
    1518            4 :             DO ispin = 1, almo_scf_env%nspins
    1519              :                CALL dbcsr_copy(almo_scf_env%matrix_t(ispin), &
    1520            4 :                                almo_scf_env%matrix_t_blk(ispin))
    1521              :             END DO
    1522              :             CALL almo_scf_xalmo_eigensolver(qs_env, almo_scf_env, &
    1523            2 :                                             arbitrary_optimizer)
    1524              : 
    1525              :          ELSE
    1526              : 
    1527            0 :             CPABORT("Other algorithms do not exist")
    1528              : 
    1529              :          END IF
    1530              : 
    1531              :       CASE (almo_deloc_xalmo_x)
    1532              : 
    1533            6 :          IF (almo_scf_env%xalmo_update_algorithm == almo_scf_pcg) THEN
    1534              : 
    1535              :             CALL almo_scf_xalmo_pcg(qs_env=qs_env, &
    1536              :                                     almo_scf_env=almo_scf_env, &
    1537              :                                     optimizer=almo_scf_env%opt_xalmo_pcg, &
    1538              :                                     quench_t=almo_scf_env%quench_t, &
    1539              :                                     matrix_t_in=almo_scf_env%matrix_t_blk, &
    1540              :                                     matrix_t_out=almo_scf_env%matrix_t, &
    1541              :                                     assume_t0_q0x=(almo_scf_env%xalmo_trial_wf == xalmo_trial_r0_out), &
    1542              :                                     perturbation_only=.TRUE., &
    1543            6 :                                     special_case=xalmo_case_normal)
    1544              : 
    1545            0 :          ELSE IF (almo_scf_env%xalmo_update_algorithm == almo_scf_trustr) THEN
    1546              : 
    1547              :             CALL almo_scf_xalmo_trustr(qs_env=qs_env, &
    1548              :                                        almo_scf_env=almo_scf_env, &
    1549              :                                        optimizer=almo_scf_env%opt_xalmo_trustr, &
    1550              :                                        quench_t=almo_scf_env%quench_t, &
    1551              :                                        matrix_t_in=almo_scf_env%matrix_t_blk, &
    1552              :                                        matrix_t_out=almo_scf_env%matrix_t, &
    1553              :                                        perturbation_only=.TRUE., &
    1554            0 :                                        special_case=xalmo_case_normal)
    1555              : 
    1556              :          ELSE
    1557              : 
    1558            0 :             CPABORT("Other algorithms do not exist")
    1559              : 
    1560              :          END IF
    1561              : 
    1562              :       CASE (almo_deloc_xalmo_scf)
    1563              : 
    1564           48 :          IF (almo_scf_env%xalmo_update_algorithm == almo_scf_diag) THEN
    1565              : 
    1566            0 :             CPABORT("Should not be here: convergence will fail!")
    1567              : 
    1568            0 :             almo_scf_env%perturbative_delocalization = .FALSE.
    1569            0 :             DO ispin = 1, almo_scf_env%nspins
    1570              :                CALL dbcsr_copy(almo_scf_env%matrix_t(ispin), &
    1571            0 :                                almo_scf_env%matrix_t_blk(ispin))
    1572              :             END DO
    1573              :             CALL almo_scf_xalmo_eigensolver(qs_env, almo_scf_env, &
    1574            0 :                                             arbitrary_optimizer)
    1575              : 
    1576           48 :          ELSE IF (almo_scf_env%xalmo_update_algorithm == almo_scf_pcg) THEN
    1577              : 
    1578              :             CALL almo_scf_xalmo_pcg(qs_env=qs_env, &
    1579              :                                     almo_scf_env=almo_scf_env, &
    1580              :                                     optimizer=almo_scf_env%opt_xalmo_pcg, &
    1581              :                                     quench_t=almo_scf_env%quench_t, &
    1582              :                                     matrix_t_in=almo_scf_env%matrix_t_blk, &
    1583              :                                     matrix_t_out=almo_scf_env%matrix_t, &
    1584              :                                     assume_t0_q0x=(almo_scf_env%xalmo_trial_wf == xalmo_trial_r0_out), &
    1585              :                                     perturbation_only=.FALSE., &
    1586           32 :                                     special_case=xalmo_case_normal)
    1587              : 
    1588              :             ! RZK-warning THIS IS A HACK TO GET ORBITAL ENERGIES
    1589           32 :             almo_experimental = .FALSE.
    1590              :             IF (almo_experimental) THEN
    1591              :                almo_scf_env%perturbative_delocalization = .TRUE.
    1592              :                !DO ispin=1,almo_scf_env%nspins
    1593              :                !   CALL dbcsr_copy(almo_scf_env%matrix_t(ispin),&
    1594              :                !           almo_scf_env%matrix_t_blk(ispin))
    1595              :                !ENDDO
    1596              :                CALL almo_scf_xalmo_eigensolver(qs_env, almo_scf_env, &
    1597              :                                                arbitrary_optimizer)
    1598              :             END IF ! experimental
    1599              : 
    1600           16 :          ELSE IF (almo_scf_env%xalmo_update_algorithm == almo_scf_trustr) THEN
    1601              : 
    1602              :             CALL almo_scf_xalmo_trustr(qs_env=qs_env, &
    1603              :                                        almo_scf_env=almo_scf_env, &
    1604              :                                        optimizer=almo_scf_env%opt_xalmo_trustr, &
    1605              :                                        quench_t=almo_scf_env%quench_t, &
    1606              :                                        matrix_t_in=almo_scf_env%matrix_t_blk, &
    1607              :                                        matrix_t_out=almo_scf_env%matrix_t, &
    1608              :                                        perturbation_only=.FALSE., &
    1609           16 :                                        special_case=xalmo_case_normal)
    1610              : 
    1611              :          ELSE
    1612              : 
    1613            0 :             CPABORT("Other algorithms do not exist")
    1614              : 
    1615              :          END IF
    1616              : 
    1617              :       CASE DEFAULT
    1618              : 
    1619          122 :          CPABORT("Illegal delocalization method")
    1620              : 
    1621              :       END SELECT
    1622              : 
    1623          148 :       SELECT CASE (almo_scf_env%deloc_method)
    1624              :       CASE (almo_deloc_scf, almo_deloc_x_then_scf)
    1625              : 
    1626           26 :          IF (almo_scf_env%deloc_truncate_virt /= virt_full) THEN
    1627            0 :             CPABORT("full scf is NYI for truncated virtual space")
    1628              :          END IF
    1629              : 
    1630          148 :          IF (almo_scf_env%xalmo_update_algorithm == almo_scf_pcg) THEN
    1631              : 
    1632              :             CALL almo_scf_xalmo_pcg(qs_env=qs_env, &
    1633              :                                     almo_scf_env=almo_scf_env, &
    1634              :                                     optimizer=almo_scf_env%opt_xalmo_pcg, &
    1635              :                                     quench_t=no_quench, &
    1636              :                                     matrix_t_in=almo_scf_env%matrix_t, &
    1637              :                                     matrix_t_out=almo_scf_env%matrix_t, &
    1638              :                                     assume_t0_q0x=.FALSE., &
    1639              :                                     perturbation_only=.FALSE., &
    1640           26 :                                     special_case=xalmo_case_fully_deloc)
    1641              : 
    1642            0 :          ELSE IF (almo_scf_env%xalmo_update_algorithm == almo_scf_trustr) THEN
    1643              : 
    1644              :             CALL almo_scf_xalmo_trustr(qs_env=qs_env, &
    1645              :                                        almo_scf_env=almo_scf_env, &
    1646              :                                        optimizer=almo_scf_env%opt_xalmo_trustr, &
    1647              :                                        quench_t=no_quench, &
    1648              :                                        matrix_t_in=almo_scf_env%matrix_t, &
    1649              :                                        matrix_t_out=almo_scf_env%matrix_t, &
    1650              :                                        perturbation_only=.FALSE., &
    1651            0 :                                        special_case=xalmo_case_fully_deloc)
    1652              : 
    1653              :          ELSE
    1654              : 
    1655            0 :             CPABORT("Other algorithms do not exist")
    1656              : 
    1657              :          END IF
    1658              : 
    1659              :       END SELECT
    1660              : 
    1661              :       ! clean up
    1662          152 :       SELECT CASE (almo_scf_env%deloc_method)
    1663              :       CASE (almo_deloc_x, almo_deloc_scf, almo_deloc_x_then_scf)
    1664           60 :          DO ispin = 1, almo_scf_env%nspins
    1665           60 :             CALL dbcsr_release(no_quench(ispin))
    1666              :          END DO
    1667          152 :          DEALLOCATE (no_quench)
    1668              :       END SELECT
    1669              : 
    1670          122 :       CALL timestop(handle)
    1671              : 
    1672          244 :    END SUBROUTINE almo_scf_delocalization
    1673              : 
    1674              : ! **************************************************************************************************
    1675              : !> \brief orbital localization
    1676              : !> \param qs_env ...
    1677              : !> \param almo_scf_env ...
    1678              : !> \par History
    1679              : !>       2018.09 created [Ziling Luo]
    1680              : !> \author Ziling Luo
    1681              : ! **************************************************************************************************
    1682          122 :    SUBROUTINE construct_nlmos(qs_env, almo_scf_env)
    1683              : 
    1684              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1685              :       TYPE(almo_scf_env_type), INTENT(INOUT)             :: almo_scf_env
    1686              : 
    1687              :       INTEGER                                            :: ispin
    1688              : 
    1689          122 :       IF (almo_scf_env%construct_nlmos) THEN
    1690              : 
    1691            8 :          DO ispin = 1, almo_scf_env%nspins
    1692              : 
    1693              :             CALL orthogonalize_mos(ket=almo_scf_env%matrix_t(ispin), &
    1694              :                                    overlap=almo_scf_env%matrix_sigma(ispin), &
    1695              :                                    metric=almo_scf_env%matrix_s(1), &
    1696              :                                    retain_locality=.FALSE., &
    1697              :                                    only_normalize=.FALSE., &
    1698              :                                    nocc_of_domain=almo_scf_env%nocc_of_domain(:, ispin), &
    1699              :                                    eps_filter=almo_scf_env%eps_filter, &
    1700              :                                    order_lanczos=almo_scf_env%order_lanczos, &
    1701              :                                    eps_lanczos=almo_scf_env%eps_lanczos, &
    1702            8 :                                    max_iter_lanczos=almo_scf_env%max_iter_lanczos)
    1703              :          END DO
    1704              : 
    1705            4 :          CALL construct_nlmos_wrapper(qs_env, almo_scf_env, virtuals=.FALSE.)
    1706              : 
    1707            4 :          IF (almo_scf_env%opt_nlmo_pcg%opt_penalty%virtual_nlmos) THEN
    1708            0 :             CALL construct_virtuals(almo_scf_env)
    1709            0 :             CALL construct_nlmos_wrapper(qs_env, almo_scf_env, virtuals=.TRUE.)
    1710              :          END IF
    1711              : 
    1712            4 :          IF (almo_scf_env%opt_nlmo_pcg%opt_penalty%compactification_filter_start > 0.0_dp) THEN
    1713            2 :             CALL nlmo_compactification(qs_env, almo_scf_env, almo_scf_env%matrix_t)
    1714              :          END IF
    1715              : 
    1716              :       END IF
    1717              : 
    1718          122 :    END SUBROUTINE construct_nlmos
    1719              : 
    1720              : ! **************************************************************************************************
    1721              : !> \brief Calls NLMO optimization
    1722              : !> \param qs_env ...
    1723              : !> \param almo_scf_env ...
    1724              : !> \param virtuals ...
    1725              : !> \par History
    1726              : !>       2019.10 created [Ziling Luo]
    1727              : !> \author Ziling Luo
    1728              : ! **************************************************************************************************
    1729            4 :    SUBROUTINE construct_nlmos_wrapper(qs_env, almo_scf_env, virtuals)
    1730              : 
    1731              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1732              :       TYPE(almo_scf_env_type), INTENT(INOUT)             :: almo_scf_env
    1733              :       LOGICAL, INTENT(IN)                                :: virtuals
    1734              : 
    1735              :       REAL(KIND=dp)                                      :: det_diff, prev_determinant
    1736              : 
    1737            4 :       almo_scf_env%overlap_determinant = 1.0
    1738              :       ! KEEP: initial_vol_coeff = almo_scf_env%opt_nlmo_pcg%opt_penalty%penalty_strength
    1739              :       almo_scf_env%opt_nlmo_pcg%opt_penalty%penalty_strength = &
    1740            4 :          -1.0_dp*almo_scf_env%opt_nlmo_pcg%opt_penalty%penalty_strength !NEW1
    1741              : 
    1742              :       ! loop over the strength of the orthogonalization penalty
    1743            4 :       prev_determinant = 10.0_dp
    1744           10 :       DO WHILE (almo_scf_env%overlap_determinant > almo_scf_env%opt_nlmo_pcg%opt_penalty%final_determinant)
    1745              : 
    1746            8 :          IF (.NOT. virtuals) THEN
    1747              :             CALL almo_scf_construct_nlmos(qs_env=qs_env, &
    1748              :                                           optimizer=almo_scf_env%opt_nlmo_pcg, &
    1749              :                                           matrix_s=almo_scf_env%matrix_s(1), &
    1750              :                                           matrix_mo_in=almo_scf_env%matrix_t, &
    1751              :                                           matrix_mo_out=almo_scf_env%matrix_t, &
    1752              :                                           template_matrix_sigma=almo_scf_env%matrix_sigma_inv, &
    1753              :                                           overlap_determinant=almo_scf_env%overlap_determinant, &
    1754              :                                           mat_distr_aos=almo_scf_env%mat_distr_aos, &
    1755              :                                           virtuals=virtuals, &
    1756            8 :                                           eps_filter=almo_scf_env%eps_filter)
    1757              :          ELSE
    1758              :             CALL almo_scf_construct_nlmos(qs_env=qs_env, &
    1759              :                                           optimizer=almo_scf_env%opt_nlmo_pcg, &
    1760              :                                           matrix_s=almo_scf_env%matrix_s(1), &
    1761              :                                           matrix_mo_in=almo_scf_env%matrix_v, &
    1762              :                                           matrix_mo_out=almo_scf_env%matrix_v, &
    1763              :                                           template_matrix_sigma=almo_scf_env%matrix_sigma_vv, &
    1764              :                                           overlap_determinant=almo_scf_env%overlap_determinant, &
    1765              :                                           mat_distr_aos=almo_scf_env%mat_distr_aos, &
    1766              :                                           virtuals=virtuals, &
    1767            0 :                                           eps_filter=almo_scf_env%eps_filter)
    1768              : 
    1769              :          END IF
    1770              : 
    1771            8 :          det_diff = prev_determinant - almo_scf_env%overlap_determinant
    1772              :          almo_scf_env%opt_nlmo_pcg%opt_penalty%penalty_strength = &
    1773              :             almo_scf_env%opt_nlmo_pcg%opt_penalty%penalty_strength/ &
    1774            8 :             ABS(almo_scf_env%opt_nlmo_pcg%opt_penalty%penalty_strength_dec_factor)
    1775              : 
    1776            8 :          IF (det_diff < almo_scf_env%opt_nlmo_pcg%opt_penalty%determinant_tolerance) THEN
    1777              :             EXIT
    1778              :          END IF
    1779            4 :          prev_determinant = almo_scf_env%overlap_determinant
    1780              : 
    1781              :       END DO
    1782              : 
    1783            4 :    END SUBROUTINE construct_nlmos_wrapper
    1784              : 
    1785              : ! **************************************************************************************************
    1786              : !> \brief Construct virtual orbitals
    1787              : !> \param almo_scf_env ...
    1788              : !> \par History
    1789              : !>       2019.10 created [Ziling Luo]
    1790              : !> \author Ziling Luo
    1791              : ! **************************************************************************************************
    1792            0 :    SUBROUTINE construct_virtuals(almo_scf_env)
    1793              : 
    1794              :       TYPE(almo_scf_env_type), INTENT(INOUT)             :: almo_scf_env
    1795              : 
    1796              :       INTEGER                                            :: ispin, n
    1797            0 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: eigenvalues
    1798              :       TYPE(dbcsr_type)                                   :: tempNV1, tempVOcc1, tempVOcc2, tempVV1, &
    1799              :                                                             tempVV2
    1800              : 
    1801            0 :       DO ispin = 1, almo_scf_env%nspins
    1802              : 
    1803              :          CALL dbcsr_create(tempNV1, &
    1804              :                            template=almo_scf_env%matrix_v(ispin), &
    1805            0 :                            matrix_type=dbcsr_type_no_symmetry)
    1806              :          CALL dbcsr_create(tempVOcc1, &
    1807              :                            template=almo_scf_env%matrix_vo(ispin), &
    1808            0 :                            matrix_type=dbcsr_type_no_symmetry)
    1809              :          CALL dbcsr_create(tempVOcc2, &
    1810              :                            template=almo_scf_env%matrix_vo(ispin), &
    1811            0 :                            matrix_type=dbcsr_type_no_symmetry)
    1812              :          CALL dbcsr_create(tempVV1, &
    1813              :                            template=almo_scf_env%matrix_sigma_vv(ispin), &
    1814            0 :                            matrix_type=dbcsr_type_no_symmetry)
    1815              :          CALL dbcsr_create(tempVV2, &
    1816              :                            template=almo_scf_env%matrix_sigma_vv(ispin), &
    1817            0 :                            matrix_type=dbcsr_type_no_symmetry)
    1818              : 
    1819              :          ! Generate random virtual matrix
    1820              :          CALL dbcsr_init_random(almo_scf_env%matrix_v(ispin), &
    1821            0 :                                 keep_sparsity=.FALSE.)
    1822              : 
    1823              :          ! Project the orbital subspace out
    1824              :          CALL dbcsr_multiply("N", "N", 1.0_dp, &
    1825              :                              almo_scf_env%matrix_s(1), &
    1826              :                              almo_scf_env%matrix_v(ispin), &
    1827              :                              0.0_dp, tempNV1, &
    1828            0 :                              filter_eps=almo_scf_env%eps_filter)
    1829              : 
    1830              :          CALL dbcsr_multiply("T", "N", 1.0_dp, &
    1831              :                              tempNV1, &
    1832              :                              almo_scf_env%matrix_t(ispin), &
    1833              :                              0.0_dp, tempVOcc1, &
    1834            0 :                              filter_eps=almo_scf_env%eps_filter)
    1835              : 
    1836              :          CALL dbcsr_multiply("N", "N", 1.0_dp, &
    1837              :                              tempVOcc1, &
    1838              :                              almo_scf_env%matrix_sigma_inv(ispin), &
    1839              :                              0.0_dp, tempVOcc2, &
    1840            0 :                              filter_eps=almo_scf_env%eps_filter)
    1841              : 
    1842              :          CALL dbcsr_multiply("N", "T", 1.0_dp, &
    1843              :                              almo_scf_env%matrix_t(ispin), &
    1844              :                              tempVOcc2, &
    1845              :                              0.0_dp, tempNV1, &
    1846            0 :                              filter_eps=almo_scf_env%eps_filter)
    1847              : 
    1848            0 :          CALL dbcsr_add(almo_scf_env%matrix_v(ispin), tempNV1, 1.0_dp, -1.0_dp)
    1849              : 
    1850              :          ! compute VxV overlap
    1851              :          CALL dbcsr_multiply("N", "N", 1.0_dp, &
    1852              :                              almo_scf_env%matrix_s(1), &
    1853              :                              almo_scf_env%matrix_v(ispin), &
    1854              :                              0.0_dp, tempNV1, &
    1855            0 :                              filter_eps=almo_scf_env%eps_filter)
    1856              : 
    1857              :          CALL dbcsr_multiply("T", "N", 1.0_dp, &
    1858              :                              almo_scf_env%matrix_v(ispin), &
    1859              :                              tempNV1, &
    1860              :                              0.0_dp, tempVV1, &
    1861            0 :                              filter_eps=almo_scf_env%eps_filter)
    1862              : 
    1863              :          CALL orthogonalize_mos(ket=almo_scf_env%matrix_v(ispin), &
    1864              :                                 overlap=tempVV1, &
    1865              :                                 metric=almo_scf_env%matrix_s(1), &
    1866              :                                 retain_locality=.FALSE., &
    1867              :                                 only_normalize=.FALSE., &
    1868              :                                 nocc_of_domain=almo_scf_env%nocc_of_domain(:, ispin), &
    1869              :                                 eps_filter=almo_scf_env%eps_filter, &
    1870              :                                 order_lanczos=almo_scf_env%order_lanczos, &
    1871              :                                 eps_lanczos=almo_scf_env%eps_lanczos, &
    1872            0 :                                 max_iter_lanczos=almo_scf_env%max_iter_lanczos)
    1873              : 
    1874              :          ! compute VxV block of the KS matrix
    1875              :          CALL dbcsr_multiply("N", "N", 1.0_dp, &
    1876              :                              almo_scf_env%matrix_ks(ispin), &
    1877              :                              almo_scf_env%matrix_v(ispin), &
    1878              :                              0.0_dp, tempNV1, &
    1879            0 :                              filter_eps=almo_scf_env%eps_filter)
    1880              : 
    1881              :          CALL dbcsr_multiply("T", "N", 1.0_dp, &
    1882              :                              almo_scf_env%matrix_v(ispin), &
    1883              :                              tempNV1, &
    1884              :                              0.0_dp, tempVV1, &
    1885            0 :                              filter_eps=almo_scf_env%eps_filter)
    1886              : 
    1887            0 :          CALL dbcsr_get_info(tempVV1, nfullrows_total=n)
    1888            0 :          ALLOCATE (eigenvalues(n))
    1889              :          CALL cp_dbcsr_syevd(tempVV1, tempVV2, &
    1890              :                              eigenvalues, &
    1891              :                              para_env=almo_scf_env%para_env, &
    1892            0 :                              blacs_env=almo_scf_env%blacs_env)
    1893            0 :          DEALLOCATE (eigenvalues)
    1894              : 
    1895              :          CALL dbcsr_multiply("N", "N", 1.0_dp, &
    1896              :                              almo_scf_env%matrix_v(ispin), &
    1897              :                              tempVV2, &
    1898              :                              0.0_dp, tempNV1, &
    1899            0 :                              filter_eps=almo_scf_env%eps_filter)
    1900              : 
    1901            0 :          CALL dbcsr_copy(almo_scf_env%matrix_v(ispin), tempNV1)
    1902              : 
    1903            0 :          CALL dbcsr_release(tempNV1)
    1904            0 :          CALL dbcsr_release(tempVOcc1)
    1905            0 :          CALL dbcsr_release(tempVOcc2)
    1906            0 :          CALL dbcsr_release(tempVV1)
    1907            0 :          CALL dbcsr_release(tempVV2)
    1908              : 
    1909              :       END DO
    1910              : 
    1911            0 :    END SUBROUTINE construct_virtuals
    1912              : 
    1913              : ! **************************************************************************************************
    1914              : !> \brief Compactify (set small blocks to zero) orbitals
    1915              : !> \param qs_env ...
    1916              : !> \param almo_scf_env ...
    1917              : !> \param matrix ...
    1918              : !> \par History
    1919              : !>       2019.10 created [Ziling Luo]
    1920              : !> \author Ziling Luo
    1921              : ! **************************************************************************************************
    1922            2 :    SUBROUTINE nlmo_compactification(qs_env, almo_scf_env, matrix)
    1923              : 
    1924              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1925              :       TYPE(almo_scf_env_type), INTENT(INOUT)             :: almo_scf_env
    1926              :       TYPE(dbcsr_type), ALLOCATABLE, DIMENSION(:), &
    1927              :          INTENT(IN)                                      :: matrix
    1928              : 
    1929              :       INTEGER                                            :: iblock_col, iblock_col_size, iblock_row, &
    1930              :                                                             iblock_row_size, icol, irow, ispin, &
    1931              :                                                             Ncols, Nrows, nspins, unit_nr
    1932              :       LOGICAL                                            :: element_by_element
    1933              :       REAL(KIND=dp)                                      :: energy, eps_local, eps_start, &
    1934              :                                                             max_element, spin_factor
    1935            2 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: occ, retained
    1936            2 :       REAL(kind=dp), DIMENSION(:, :), POINTER            :: data_p
    1937              :       TYPE(cp_logger_type), POINTER                      :: logger
    1938              :       TYPE(dbcsr_iterator_type)                          :: iter
    1939            2 :       TYPE(dbcsr_type), ALLOCATABLE, DIMENSION(:)        :: matrix_p_tmp, matrix_t_tmp
    1940              :       TYPE(mp_comm_type)                                 :: group
    1941              : 
    1942              :       ! define the output_unit
    1943            4 :       logger => cp_get_default_logger()
    1944            2 :       IF (logger%para_env%is_source()) THEN
    1945            1 :          unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
    1946              :       ELSE
    1947              :          unit_nr = -1
    1948              :       END IF
    1949              : 
    1950            2 :       nspins = SIZE(matrix)
    1951            2 :       element_by_element = .FALSE.
    1952              : 
    1953            2 :       IF (nspins == 1) THEN
    1954            2 :          spin_factor = 2.0_dp
    1955              :       ELSE
    1956            0 :          spin_factor = 1.0_dp
    1957              :       END IF
    1958              : 
    1959            8 :       ALLOCATE (matrix_t_tmp(nspins))
    1960            6 :       ALLOCATE (matrix_p_tmp(nspins))
    1961            6 :       ALLOCATE (retained(nspins))
    1962            2 :       ALLOCATE (occ(2))
    1963              : 
    1964            4 :       DO ispin = 1, nspins
    1965              : 
    1966              :          ! init temporary storage
    1967              :          CALL dbcsr_create(matrix_t_tmp(ispin), &
    1968              :                            template=matrix(ispin), &
    1969            2 :                            matrix_type=dbcsr_type_no_symmetry)
    1970            2 :          CALL dbcsr_copy(matrix_t_tmp(ispin), matrix(ispin))
    1971              : 
    1972              :          CALL dbcsr_create(matrix_p_tmp(ispin), &
    1973              :                            template=almo_scf_env%matrix_p(ispin), &
    1974            2 :                            matrix_type=dbcsr_type_no_symmetry)
    1975            4 :          CALL dbcsr_copy(matrix_p_tmp(ispin), almo_scf_env%matrix_p(ispin))
    1976              : 
    1977              :       END DO
    1978              : 
    1979            2 :       IF (unit_nr > 0) THEN
    1980            1 :          WRITE (unit_nr, *)
    1981              :          WRITE (unit_nr, '(T2,A)') &
    1982            1 :             "Energy dependence on the (block-by-block) filtering of the NLMO coefficients"
    1983              :          IF (unit_nr > 0) WRITE (unit_nr, '(T2,A13,A20,A20,A25)') &
    1984            1 :             "EPS filter", "Occupation Alpha", "Occupation Beta", "Energy"
    1985              :       END IF
    1986              : 
    1987            2 :       eps_start = almo_scf_env%opt_nlmo_pcg%opt_penalty%compactification_filter_start
    1988            2 :       eps_local = MAX(eps_start, 10E-14_dp)
    1989              : 
    1990            8 :       DO
    1991              : 
    1992           10 :          IF (eps_local > 0.11_dp) EXIT
    1993              : 
    1994           16 :          DO ispin = 1, nspins
    1995              : 
    1996            8 :             retained(ispin) = 0
    1997            8 :             CALL dbcsr_work_create(matrix_t_tmp(ispin), work_mutable=.TRUE.)
    1998            8 :             CALL dbcsr_iterator_start(iter, matrix_t_tmp(ispin))
    1999          264 :             DO WHILE (dbcsr_iterator_blocks_left(iter))
    2000              :                CALL dbcsr_iterator_next_block(iter, iblock_row, iblock_col, data_p, &
    2001          256 :                                               row_size=iblock_row_size, col_size=iblock_col_size)
    2002          776 :                DO icol = 1, iblock_col_size
    2003              : 
    2004          256 :                   IF (element_by_element) THEN
    2005              : 
    2006              :                      DO irow = 1, iblock_row_size
    2007              :                         IF (ABS(data_p(irow, icol)) < eps_local) THEN
    2008              :                            data_p(irow, icol) = 0.0_dp
    2009              :                         ELSE
    2010              :                            retained(ispin) = retained(ispin) + 1
    2011              :                         END IF
    2012              :                      END DO
    2013              : 
    2014              :                   ELSE ! rows are blocked
    2015              : 
    2016          512 :                      max_element = 0.0_dp
    2017         2560 :                      DO irow = 1, iblock_row_size
    2018         2560 :                         IF (ABS(data_p(irow, icol)) > max_element) THEN
    2019              :                            max_element = ABS(data_p(irow, icol))
    2020              :                         END IF
    2021              :                      END DO
    2022          512 :                      IF (max_element < eps_local) THEN
    2023          155 :                         DO irow = 1, iblock_row_size
    2024          155 :                            data_p(irow, icol) = 0.0_dp
    2025              :                         END DO
    2026              :                      ELSE
    2027          481 :                         retained(ispin) = retained(ispin) + iblock_row_size
    2028              :                      END IF
    2029              : 
    2030              :                   END IF ! block rows?
    2031              :                END DO ! icol
    2032              : 
    2033              :             END DO ! iterator
    2034            8 :             CALL dbcsr_iterator_stop(iter)
    2035            8 :             CALL dbcsr_finalize(matrix_t_tmp(ispin))
    2036            8 :             CALL dbcsr_filter(matrix_t_tmp(ispin), eps_local)
    2037              : 
    2038              :             CALL dbcsr_get_info(matrix_t_tmp(ispin), group=group, &
    2039              :                                 nfullrows_total=Nrows, &
    2040            8 :                                 nfullcols_total=Ncols)
    2041            8 :             CALL group%sum(retained(ispin))
    2042              : 
    2043              :             !devide by the total no. elements
    2044            8 :             occ(ispin) = retained(ispin)/Nrows/Ncols
    2045              : 
    2046              :             ! compute the global projectors (for the density matrix)
    2047              :             CALL almo_scf_t_to_proj( &
    2048              :                t=matrix_t_tmp(ispin), &
    2049              :                p=matrix_p_tmp(ispin), &
    2050              :                eps_filter=almo_scf_env%eps_filter, &
    2051              :                orthog_orbs=.FALSE., &
    2052              :                nocc_of_domain=almo_scf_env%nocc_of_domain(:, ispin), &
    2053              :                s=almo_scf_env%matrix_s(1), &
    2054              :                sigma=almo_scf_env%matrix_sigma(ispin), &
    2055              :                sigma_inv=almo_scf_env%matrix_sigma_inv(ispin), &
    2056              :                use_guess=.FALSE., &
    2057              :                algorithm=almo_scf_env%sigma_inv_algorithm, &
    2058              :                inv_eps_factor=almo_scf_env%matrix_iter_eps_error_factor, &
    2059              :                inverse_accelerator=almo_scf_env%order_lanczos, &
    2060              :                eps_lanczos=almo_scf_env%eps_lanczos, &
    2061              :                max_iter_lanczos=almo_scf_env%max_iter_lanczos, &
    2062              :                para_env=almo_scf_env%para_env, &
    2063            8 :                blacs_env=almo_scf_env%blacs_env)
    2064              : 
    2065              :             ! compute dm from the projector(s)
    2066           32 :             CALL dbcsr_scale(matrix_p_tmp(ispin), spin_factor)
    2067              : 
    2068              :          END DO
    2069              : 
    2070              :          ! the KS matrix is updated outside the spin loop
    2071              :          CALL almo_dm_to_almo_ks(qs_env, &
    2072              :                                  matrix_p_tmp, &
    2073              :                                  almo_scf_env%matrix_ks, &
    2074              :                                  energy, &
    2075              :                                  almo_scf_env%eps_filter, &
    2076            8 :                                  almo_scf_env%mat_distr_aos)
    2077              : 
    2078            8 :          IF (nspins < 2) occ(2) = occ(1)
    2079            8 :          IF (unit_nr > 0) WRITE (unit_nr, '(T2,E13.3,F20.10,F20.10,F25.15)') &
    2080            4 :             eps_local, occ(1), occ(2), energy
    2081              : 
    2082            8 :          eps_local = 2.0_dp*eps_local
    2083              : 
    2084              :       END DO
    2085              : 
    2086            4 :       DO ispin = 1, nspins
    2087              : 
    2088            2 :          CALL dbcsr_release(matrix_t_tmp(ispin))
    2089            4 :          CALL dbcsr_release(matrix_p_tmp(ispin))
    2090              : 
    2091              :       END DO
    2092              : 
    2093            2 :       DEALLOCATE (matrix_t_tmp)
    2094            2 :       DEALLOCATE (matrix_p_tmp)
    2095            2 :       DEALLOCATE (occ)
    2096            2 :       DEALLOCATE (retained)
    2097              : 
    2098            2 :    END SUBROUTINE nlmo_compactification
    2099              : 
    2100              : ! *****************************************************************************
    2101              : !> \brief after SCF we have the final density and KS matrices compute various
    2102              : !>        post-scf quantities
    2103              : !> \param qs_env ...
    2104              : !> \param almo_scf_env ...
    2105              : !> \par History
    2106              : !>       2015.03 created  [Rustam Z. Khaliullin]
    2107              : !> \author Rustam Z. Khaliullin
    2108              : ! **************************************************************************************************
    2109          122 :    SUBROUTINE almo_scf_post(qs_env, almo_scf_env)
    2110              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    2111              :       TYPE(almo_scf_env_type), INTENT(INOUT)             :: almo_scf_env
    2112              : 
    2113              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'almo_scf_post'
    2114              : 
    2115              :       INTEGER                                            :: handle, ispin
    2116              :       TYPE(cp_fm_type), POINTER                          :: mo_coeff
    2117          122 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_w
    2118          122 :       TYPE(dbcsr_type), ALLOCATABLE, DIMENSION(:)        :: matrix_t_processed
    2119          122 :       TYPE(mo_set_type), DIMENSION(:), POINTER           :: mos
    2120              :       TYPE(qs_scf_env_type), POINTER                     :: scf_env
    2121              : 
    2122          122 :       CALL timeset(routineN, handle)
    2123              : 
    2124              :       ! store matrices to speed up the next scf run
    2125          122 :       CALL almo_scf_store_extrapolation_data(almo_scf_env)
    2126              : 
    2127              :       ! orthogonalize orbitals before returning them to QS
    2128          494 :       ALLOCATE (matrix_t_processed(almo_scf_env%nspins))
    2129              :       !ALLOCATE (matrix_v_processed(almo_scf_env%nspins))
    2130              : 
    2131          250 :       DO ispin = 1, almo_scf_env%nspins
    2132              : 
    2133              :          CALL dbcsr_create(matrix_t_processed(ispin), &
    2134              :                            template=almo_scf_env%matrix_t(ispin), &
    2135          128 :                            matrix_type=dbcsr_type_no_symmetry)
    2136              : 
    2137              :          CALL dbcsr_copy(matrix_t_processed(ispin), &
    2138          128 :                          almo_scf_env%matrix_t(ispin))
    2139              : 
    2140          250 :          IF (almo_scf_env%return_orthogonalized_mos) THEN
    2141              : 
    2142              :             CALL orthogonalize_mos(ket=matrix_t_processed(ispin), &
    2143              :                                    overlap=almo_scf_env%matrix_sigma(ispin), &
    2144              :                                    metric=almo_scf_env%matrix_s(1), &
    2145              :                                    retain_locality=.FALSE., &
    2146              :                                    only_normalize=.FALSE., &
    2147              :                                    nocc_of_domain=almo_scf_env%nocc_of_domain(:, ispin), &
    2148              :                                    eps_filter=almo_scf_env%eps_filter, &
    2149              :                                    order_lanczos=almo_scf_env%order_lanczos, &
    2150              :                                    eps_lanczos=almo_scf_env%eps_lanczos, &
    2151              :                                    max_iter_lanczos=almo_scf_env%max_iter_lanczos, &
    2152          106 :                                    smear=almo_scf_env%smear)
    2153              :          END IF
    2154              : 
    2155              :       END DO
    2156              : 
    2157              :       !! RS-WARNING: If smearing ALMO is requested, rescaled fully-occupied orbitals are returned to QS
    2158              :       !! RS-WARNING: Beware that QS will not be informed about electronic entropy.
    2159              :       !!             If you want a quick and dirty transfer to QS energy, uncomment the following hack:
    2160              :       !! IF (almo_scf_env%smear) THEN
    2161              :       !!    qs_env%energy%kTS = 0.0_dp
    2162              :       !!    DO ispin = 1, almo_scf_env%nspins
    2163              :       !!       qs_env%energy%kTS = qs_env%energy%kTS + almo_scf_env%kTS(ispin)
    2164              :       !!    END DO
    2165              :       !! END IF
    2166              : 
    2167              :       ! return orbitals to QS
    2168          122 :       NULLIFY (mos, mo_coeff, scf_env)
    2169              : 
    2170          122 :       CALL get_qs_env(qs_env, mos=mos, scf_env=scf_env)
    2171              : 
    2172          250 :       DO ispin = 1, almo_scf_env%nspins
    2173              : 
    2174              :          ! Currently only fm version of mo_set is usable.
    2175              :          ! First transform the matrix_t to fm version
    2176          128 :          CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff)
    2177          128 :          CALL copy_dbcsr_to_fm(matrix_t_processed(ispin), mo_coeff)
    2178          250 :          CALL dbcsr_release(matrix_t_processed(ispin))
    2179              :       END DO
    2180          250 :       DO ispin = 1, almo_scf_env%nspins
    2181          250 :          CALL dbcsr_release(matrix_t_processed(ispin))
    2182              :       END DO
    2183          122 :       DEALLOCATE (matrix_t_processed)
    2184              : 
    2185              :       ! calculate post scf properties
    2186              : 
    2187          122 :       CALL almo_post_scf_compute_properties(qs_env)
    2188              : 
    2189              :       ! compute the W matrix if associated
    2190          122 :       IF (almo_scf_env%calc_forces) THEN
    2191           66 :          CALL get_qs_env(qs_env, matrix_w=matrix_w)
    2192           66 :          IF (ASSOCIATED(matrix_w)) THEN
    2193           66 :             CALL calculate_w_matrix_almo(matrix_w, almo_scf_env)
    2194              :          ELSE
    2195            0 :             CPABORT("Matrix W is needed but not associated")
    2196              :          END IF
    2197              :       END IF
    2198              : 
    2199          122 :       CALL timestop(handle)
    2200              : 
    2201          122 :    END SUBROUTINE almo_scf_post
    2202              : 
    2203              : ! **************************************************************************************************
    2204              : !> \brief create various matrices
    2205              : !> \param almo_scf_env ...
    2206              : !> \param matrix_s0 ...
    2207              : !> \par History
    2208              : !>       2011.07 created [Rustam Z Khaliullin]
    2209              : !> \author Rustam Z Khaliullin
    2210              : ! **************************************************************************************************
    2211          122 :    SUBROUTINE almo_scf_env_create_matrices(almo_scf_env, matrix_s0)
    2212              : 
    2213              :       TYPE(almo_scf_env_type), INTENT(INOUT)             :: almo_scf_env
    2214              :       TYPE(dbcsr_type), INTENT(IN)                       :: matrix_s0
    2215              : 
    2216              :       CHARACTER(len=*), PARAMETER :: routineN = 'almo_scf_env_create_matrices'
    2217              : 
    2218              :       INTEGER                                            :: handle, ispin, nspins
    2219              : 
    2220          122 :       CALL timeset(routineN, handle)
    2221              : 
    2222          122 :       nspins = almo_scf_env%nspins
    2223              : 
    2224              :       ! AO overlap matrix and its various functions
    2225              :       CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_s(1), &
    2226              :                               matrix_qs=matrix_s0, &
    2227              :                               almo_scf_env=almo_scf_env, &
    2228              :                               name_new="S", &
    2229              :                               size_keys=[almo_mat_dim_aobasis, almo_mat_dim_aobasis], &
    2230              :                               symmetry_new=dbcsr_type_symmetric, &
    2231              :                               spin_key=0, &
    2232          122 :                               init_domains=.FALSE.)
    2233              :       CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_s_blk(1), &
    2234              :                               matrix_qs=matrix_s0, &
    2235              :                               almo_scf_env=almo_scf_env, &
    2236              :                               name_new="S_BLK", &
    2237              :                               size_keys=[almo_mat_dim_aobasis, almo_mat_dim_aobasis], &
    2238              :                               symmetry_new=dbcsr_type_symmetric, &
    2239              :                               spin_key=0, &
    2240          122 :                               init_domains=.TRUE.)
    2241          122 :       IF (almo_scf_env%almo_update_algorithm == almo_scf_diag) THEN
    2242              :          CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_s_blk_sqrt_inv(1), &
    2243              :                                  matrix_qs=matrix_s0, &
    2244              :                                  almo_scf_env=almo_scf_env, &
    2245              :                                  name_new="S_BLK_SQRT_INV", &
    2246              :                                  size_keys=[almo_mat_dim_aobasis, almo_mat_dim_aobasis], &
    2247              :                                  symmetry_new=dbcsr_type_symmetric, &
    2248              :                                  spin_key=0, &
    2249           76 :                                  init_domains=.TRUE.)
    2250              :          CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_s_blk_sqrt(1), &
    2251              :                                  matrix_qs=matrix_s0, &
    2252              :                                  almo_scf_env=almo_scf_env, &
    2253              :                                  name_new="S_BLK_SQRT", &
    2254              :                                  size_keys=[almo_mat_dim_aobasis, almo_mat_dim_aobasis], &
    2255              :                                  symmetry_new=dbcsr_type_symmetric, &
    2256              :                                  spin_key=0, &
    2257           76 :                                  init_domains=.TRUE.)
    2258           46 :       ELSE IF (almo_scf_env%almo_update_algorithm == almo_scf_dm_sign) THEN
    2259              :          CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_s_blk_inv(1), &
    2260              :                                  matrix_qs=matrix_s0, &
    2261              :                                  almo_scf_env=almo_scf_env, &
    2262              :                                  name_new="S_BLK_INV", &
    2263              :                                  size_keys=[almo_mat_dim_aobasis, almo_mat_dim_aobasis], &
    2264              :                                  symmetry_new=dbcsr_type_symmetric, &
    2265              :                                  spin_key=0, &
    2266            0 :                                  init_domains=.TRUE.)
    2267              :       END IF
    2268              : 
    2269              :       ! MO coeff matrices and their derivatives
    2270          494 :       ALLOCATE (almo_scf_env%matrix_t_blk(nspins))
    2271          372 :       ALLOCATE (almo_scf_env%quench_t_blk(nspins))
    2272          372 :       ALLOCATE (almo_scf_env%matrix_err_blk(nspins))
    2273          372 :       ALLOCATE (almo_scf_env%matrix_err_xx(nspins))
    2274          372 :       ALLOCATE (almo_scf_env%matrix_sigma(nspins))
    2275          372 :       ALLOCATE (almo_scf_env%matrix_sigma_inv(nspins))
    2276          372 :       ALLOCATE (almo_scf_env%matrix_sigma_sqrt(nspins))
    2277          372 :       ALLOCATE (almo_scf_env%matrix_sigma_sqrt_inv(nspins))
    2278          372 :       ALLOCATE (almo_scf_env%matrix_sigma_blk(nspins))
    2279          372 :       ALLOCATE (almo_scf_env%matrix_sigma_inv_0deloc(nspins))
    2280          372 :       ALLOCATE (almo_scf_env%matrix_t(nspins))
    2281          372 :       ALLOCATE (almo_scf_env%matrix_t_tr(nspins))
    2282          250 :       DO ispin = 1, nspins
    2283              :          ! create the blocked quencher
    2284              :          CALL matrix_almo_create(matrix_new=almo_scf_env%quench_t_blk(ispin), &
    2285              :                                  matrix_qs=matrix_s0, &
    2286              :                                  almo_scf_env=almo_scf_env, &
    2287              :                                  name_new="Q_BLK", &
    2288              :                                  size_keys=[almo_mat_dim_aobasis, almo_mat_dim_occ], &
    2289              :                                  symmetry_new=dbcsr_type_no_symmetry, &
    2290              :                                  spin_key=ispin, &
    2291          128 :                                  init_domains=.TRUE.)
    2292              :          ! create ALMO coefficient matrix
    2293              :          CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_t_blk(ispin), &
    2294              :                                  matrix_qs=matrix_s0, &
    2295              :                                  almo_scf_env=almo_scf_env, &
    2296              :                                  name_new="T_BLK", &
    2297              :                                  size_keys=[almo_mat_dim_aobasis, almo_mat_dim_occ], &
    2298              :                                  symmetry_new=dbcsr_type_no_symmetry, &
    2299              :                                  spin_key=ispin, &
    2300          128 :                                  init_domains=.TRUE.)
    2301              :          ! create the error matrix
    2302              :          CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_err_blk(ispin), &
    2303              :                                  matrix_qs=matrix_s0, &
    2304              :                                  almo_scf_env=almo_scf_env, &
    2305              :                                  name_new="ERR_BLK", &
    2306              :                                  size_keys=[almo_mat_dim_aobasis, almo_mat_dim_aobasis], &
    2307              :                                  symmetry_new=dbcsr_type_no_symmetry, &
    2308              :                                  spin_key=ispin, &
    2309          128 :                                  init_domains=.TRUE.)
    2310              :          ! create the error matrix for the quenched ALMOs
    2311              :          CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_err_xx(ispin), &
    2312              :                                  matrix_qs=matrix_s0, &
    2313              :                                  almo_scf_env=almo_scf_env, &
    2314              :                                  name_new="ERR_XX", &
    2315              :                                  size_keys=[almo_mat_dim_aobasis, almo_mat_dim_occ], &
    2316              :                                  symmetry_new=dbcsr_type_no_symmetry, &
    2317              :                                  spin_key=ispin, &
    2318          128 :                                  init_domains=.FALSE.)
    2319              :          ! create a matrix with dimensions of a transposed mo coefficient matrix
    2320              :          ! it might be necessary to perform the correction step using cayley
    2321              :          CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_t_tr(ispin), &
    2322              :                                  matrix_qs=matrix_s0, &
    2323              :                                  almo_scf_env=almo_scf_env, &
    2324              :                                  name_new="T_TR", &
    2325              :                                  size_keys=[almo_mat_dim_occ, almo_mat_dim_aobasis], &
    2326              :                                  symmetry_new=dbcsr_type_no_symmetry, &
    2327              :                                  spin_key=ispin, &
    2328          128 :                                  init_domains=.FALSE.)
    2329              :          ! create mo overlap matrix
    2330              :          CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_sigma(ispin), &
    2331              :                                  matrix_qs=matrix_s0, &
    2332              :                                  almo_scf_env=almo_scf_env, &
    2333              :                                  name_new="SIG", &
    2334              :                                  size_keys=[almo_mat_dim_occ, almo_mat_dim_occ], &
    2335              :                                  symmetry_new=dbcsr_type_symmetric, &
    2336              :                                  spin_key=ispin, &
    2337          128 :                                  init_domains=.FALSE.)
    2338              :          ! create blocked mo overlap matrix
    2339              :          CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_sigma_blk(ispin), &
    2340              :                                  matrix_qs=matrix_s0, &
    2341              :                                  almo_scf_env=almo_scf_env, &
    2342              :                                  name_new="SIG_BLK", &
    2343              :                                  size_keys=[almo_mat_dim_occ, almo_mat_dim_occ], &
    2344              :                                  symmetry_new=dbcsr_type_symmetric, &
    2345              :                                  spin_key=ispin, &
    2346          128 :                                  init_domains=.TRUE.)
    2347              :          ! create blocked inverse mo overlap matrix
    2348              :          CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_sigma_inv_0deloc(ispin), &
    2349              :                                  matrix_qs=matrix_s0, &
    2350              :                                  almo_scf_env=almo_scf_env, &
    2351              :                                  name_new="SIGINV_BLK", &
    2352              :                                  size_keys=[almo_mat_dim_occ, almo_mat_dim_occ], &
    2353              :                                  symmetry_new=dbcsr_type_symmetric, &
    2354              :                                  spin_key=ispin, &
    2355          128 :                                  init_domains=.TRUE.)
    2356              :          ! create inverse mo overlap matrix
    2357              :          CALL matrix_almo_create( &
    2358              :             matrix_new=almo_scf_env%matrix_sigma_inv(ispin), &
    2359              :             matrix_qs=matrix_s0, &
    2360              :             almo_scf_env=almo_scf_env, &
    2361              :             name_new="SIGINV", &
    2362              :             size_keys=[almo_mat_dim_occ, almo_mat_dim_occ], &
    2363              :             symmetry_new=dbcsr_type_symmetric, &
    2364              :             spin_key=ispin, &
    2365          128 :             init_domains=.FALSE.)
    2366              :          ! create various templates that will be necessary later
    2367              :          CALL matrix_almo_create( &
    2368              :             matrix_new=almo_scf_env%matrix_t(ispin), &
    2369              :             matrix_qs=matrix_s0, &
    2370              :             almo_scf_env=almo_scf_env, &
    2371              :             name_new="T", &
    2372              :             size_keys=[almo_mat_dim_aobasis, almo_mat_dim_occ], &
    2373              :             symmetry_new=dbcsr_type_no_symmetry, &
    2374              :             spin_key=ispin, &
    2375          128 :             init_domains=.FALSE.)
    2376              :          CALL dbcsr_create(almo_scf_env%matrix_sigma_sqrt(ispin), &
    2377              :                            template=almo_scf_env%matrix_sigma(ispin), &
    2378          128 :                            matrix_type=dbcsr_type_no_symmetry)
    2379              :          CALL dbcsr_create(almo_scf_env%matrix_sigma_sqrt_inv(ispin), &
    2380              :                            template=almo_scf_env%matrix_sigma(ispin), &
    2381          250 :                            matrix_type=dbcsr_type_no_symmetry)
    2382              :       END DO
    2383              : 
    2384              :       ! create virtual orbitals if necessary
    2385          122 :       IF (almo_scf_env%need_virtuals) THEN
    2386          372 :          ALLOCATE (almo_scf_env%matrix_v_blk(nspins))
    2387          372 :          ALLOCATE (almo_scf_env%matrix_v_full_blk(nspins))
    2388          372 :          ALLOCATE (almo_scf_env%matrix_v(nspins))
    2389          372 :          ALLOCATE (almo_scf_env%matrix_vo(nspins))
    2390          372 :          ALLOCATE (almo_scf_env%matrix_x(nspins))
    2391          372 :          ALLOCATE (almo_scf_env%matrix_ov(nspins))
    2392          372 :          ALLOCATE (almo_scf_env%matrix_ov_full(nspins))
    2393          372 :          ALLOCATE (almo_scf_env%matrix_sigma_vv(nspins))
    2394          372 :          ALLOCATE (almo_scf_env%matrix_sigma_vv_blk(nspins))
    2395          372 :          ALLOCATE (almo_scf_env%matrix_sigma_vv_sqrt(nspins))
    2396          372 :          ALLOCATE (almo_scf_env%matrix_sigma_vv_sqrt_inv(nspins))
    2397          372 :          ALLOCATE (almo_scf_env%matrix_vv_full_blk(nspins))
    2398              : 
    2399          122 :          IF (almo_scf_env%deloc_truncate_virt /= virt_full) THEN
    2400            0 :             ALLOCATE (almo_scf_env%matrix_k_blk(nspins))
    2401            0 :             ALLOCATE (almo_scf_env%matrix_k_blk_ones(nspins))
    2402            0 :             ALLOCATE (almo_scf_env%matrix_k_tr(nspins))
    2403            0 :             ALLOCATE (almo_scf_env%matrix_v_disc(nspins))
    2404            0 :             ALLOCATE (almo_scf_env%matrix_v_disc_blk(nspins))
    2405            0 :             ALLOCATE (almo_scf_env%matrix_ov_disc(nspins))
    2406            0 :             ALLOCATE (almo_scf_env%matrix_vv_disc_blk(nspins))
    2407            0 :             ALLOCATE (almo_scf_env%matrix_vv_disc(nspins))
    2408            0 :             ALLOCATE (almo_scf_env%opt_k_t_dd(nspins))
    2409            0 :             ALLOCATE (almo_scf_env%opt_k_t_rr(nspins))
    2410            0 :             ALLOCATE (almo_scf_env%opt_k_denom(nspins))
    2411              :          END IF
    2412              : 
    2413          250 :          DO ispin = 1, nspins
    2414              :             CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_v_full_blk(ispin), &
    2415              :                                     matrix_qs=matrix_s0, &
    2416              :                                     almo_scf_env=almo_scf_env, &
    2417              :                                     name_new="V_FULL_BLK", &
    2418              :                                     size_keys=[almo_mat_dim_aobasis, almo_mat_dim_virt_full], &
    2419              :                                     symmetry_new=dbcsr_type_no_symmetry, &
    2420              :                                     spin_key=ispin, &
    2421          128 :                                     init_domains=.FALSE.)
    2422              :             CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_v_blk(ispin), &
    2423              :                                     matrix_qs=matrix_s0, &
    2424              :                                     almo_scf_env=almo_scf_env, &
    2425              :                                     name_new="V_BLK", &
    2426              :                                     size_keys=[almo_mat_dim_aobasis, almo_mat_dim_virt], &
    2427              :                                     symmetry_new=dbcsr_type_no_symmetry, &
    2428              :                                     spin_key=ispin, &
    2429          128 :                                     init_domains=.FALSE.)
    2430              :             CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_v(ispin), &
    2431              :                                     matrix_qs=matrix_s0, &
    2432              :                                     almo_scf_env=almo_scf_env, &
    2433              :                                     name_new="V", &
    2434              :                                     size_keys=[almo_mat_dim_aobasis, almo_mat_dim_virt], &
    2435              :                                     symmetry_new=dbcsr_type_no_symmetry, &
    2436              :                                     spin_key=ispin, &
    2437          128 :                                     init_domains=.FALSE.)
    2438              :             CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_ov_full(ispin), &
    2439              :                                     matrix_qs=matrix_s0, &
    2440              :                                     almo_scf_env=almo_scf_env, &
    2441              :                                     name_new="OV_FULL", &
    2442              :                                     size_keys=[almo_mat_dim_occ, almo_mat_dim_virt_full], &
    2443              :                                     symmetry_new=dbcsr_type_no_symmetry, &
    2444              :                                     spin_key=ispin, &
    2445          128 :                                     init_domains=.FALSE.)
    2446              :             CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_ov(ispin), &
    2447              :                                     matrix_qs=matrix_s0, &
    2448              :                                     almo_scf_env=almo_scf_env, &
    2449              :                                     name_new="OV", &
    2450              :                                     size_keys=[almo_mat_dim_occ, almo_mat_dim_virt], &
    2451              :                                     symmetry_new=dbcsr_type_no_symmetry, &
    2452              :                                     spin_key=ispin, &
    2453          128 :                                     init_domains=.FALSE.)
    2454              :             CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_vo(ispin), &
    2455              :                                     matrix_qs=matrix_s0, &
    2456              :                                     almo_scf_env=almo_scf_env, &
    2457              :                                     name_new="VO", &
    2458              :                                     size_keys=[almo_mat_dim_virt, almo_mat_dim_occ], &
    2459              :                                     symmetry_new=dbcsr_type_no_symmetry, &
    2460              :                                     spin_key=ispin, &
    2461          128 :                                     init_domains=.FALSE.)
    2462              :             CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_x(ispin), &
    2463              :                                     matrix_qs=matrix_s0, &
    2464              :                                     almo_scf_env=almo_scf_env, &
    2465              :                                     name_new="VO", &
    2466              :                                     size_keys=[almo_mat_dim_virt, almo_mat_dim_occ], &
    2467              :                                     symmetry_new=dbcsr_type_no_symmetry, &
    2468              :                                     spin_key=ispin, &
    2469          128 :                                     init_domains=.FALSE.)
    2470              :             CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_sigma_vv(ispin), &
    2471              :                                     matrix_qs=matrix_s0, &
    2472              :                                     almo_scf_env=almo_scf_env, &
    2473              :                                     name_new="SIG_VV", &
    2474              :                                     size_keys=[almo_mat_dim_virt, almo_mat_dim_virt], &
    2475              :                                     symmetry_new=dbcsr_type_symmetric, &
    2476              :                                     spin_key=ispin, &
    2477          128 :                                     init_domains=.FALSE.)
    2478              :             CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_vv_full_blk(ispin), &
    2479              :                                     matrix_qs=matrix_s0, &
    2480              :                                     almo_scf_env=almo_scf_env, &
    2481              :                                     name_new="VV_FULL_BLK", &
    2482              :                                     size_keys=[almo_mat_dim_virt_full, almo_mat_dim_virt_full], &
    2483              :                                     symmetry_new=dbcsr_type_no_symmetry, &
    2484              :                                     spin_key=ispin, &
    2485          128 :                                     init_domains=.TRUE.)
    2486              :             CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_sigma_vv_blk(ispin), &
    2487              :                                     matrix_qs=matrix_s0, &
    2488              :                                     almo_scf_env=almo_scf_env, &
    2489              :                                     name_new="SIG_VV_BLK", &
    2490              :                                     size_keys=[almo_mat_dim_virt, almo_mat_dim_virt], &
    2491              :                                     symmetry_new=dbcsr_type_symmetric, &
    2492              :                                     spin_key=ispin, &
    2493          128 :                                     init_domains=.TRUE.)
    2494              :             CALL dbcsr_create(almo_scf_env%matrix_sigma_vv_sqrt(ispin), &
    2495              :                               template=almo_scf_env%matrix_sigma_vv(ispin), &
    2496          128 :                               matrix_type=dbcsr_type_no_symmetry)
    2497              :             CALL dbcsr_create(almo_scf_env%matrix_sigma_vv_sqrt_inv(ispin), &
    2498              :                               template=almo_scf_env%matrix_sigma_vv(ispin), &
    2499          128 :                               matrix_type=dbcsr_type_no_symmetry)
    2500              : 
    2501          250 :             IF (almo_scf_env%deloc_truncate_virt /= virt_full) THEN
    2502              :                CALL matrix_almo_create(matrix_new=almo_scf_env%opt_k_t_rr(ispin), &
    2503              :                                        matrix_qs=matrix_s0, &
    2504              :                                        almo_scf_env=almo_scf_env, &
    2505              :                                        name_new="OPT_K_U_RR", &
    2506              :                                        size_keys=[almo_mat_dim_virt, almo_mat_dim_virt], &
    2507              :                                        symmetry_new=dbcsr_type_no_symmetry, &
    2508              :                                        spin_key=ispin, &
    2509            0 :                                        init_domains=.FALSE.)
    2510              :                CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_vv_disc(ispin), &
    2511              :                                        matrix_qs=matrix_s0, &
    2512              :                                        almo_scf_env=almo_scf_env, &
    2513              :                                        name_new="VV_DISC", &
    2514              :                                        size_keys=[almo_mat_dim_virt_disc, almo_mat_dim_virt_disc], &
    2515              :                                        symmetry_new=dbcsr_type_symmetric, &
    2516              :                                        spin_key=ispin, &
    2517            0 :                                        init_domains=.FALSE.)
    2518              :                CALL matrix_almo_create(matrix_new=almo_scf_env%opt_k_t_dd(ispin), &
    2519              :                                        matrix_qs=matrix_s0, &
    2520              :                                        almo_scf_env=almo_scf_env, &
    2521              :                                        name_new="OPT_K_U_DD", &
    2522              :                                        size_keys=[almo_mat_dim_virt_disc, almo_mat_dim_virt_disc], &
    2523              :                                        symmetry_new=dbcsr_type_no_symmetry, &
    2524              :                                        spin_key=ispin, &
    2525            0 :                                        init_domains=.FALSE.)
    2526              :                CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_vv_disc_blk(ispin), &
    2527              :                                        matrix_qs=matrix_s0, &
    2528              :                                        almo_scf_env=almo_scf_env, &
    2529              :                                        name_new="VV_DISC_BLK", &
    2530              :                                        size_keys=[almo_mat_dim_virt_disc, almo_mat_dim_virt_disc], &
    2531              :                                        symmetry_new=dbcsr_type_symmetric, &
    2532              :                                        spin_key=ispin, &
    2533            0 :                                        init_domains=.TRUE.)
    2534              :                CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_k_blk(ispin), &
    2535              :                                        matrix_qs=matrix_s0, &
    2536              :                                        almo_scf_env=almo_scf_env, &
    2537              :                                        name_new="K_BLK", &
    2538              :                                        size_keys=[almo_mat_dim_virt_disc, almo_mat_dim_virt], &
    2539              :                                        symmetry_new=dbcsr_type_no_symmetry, &
    2540              :                                        spin_key=ispin, &
    2541            0 :                                        init_domains=.TRUE.)
    2542              :                CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_k_blk_ones(ispin), &
    2543              :                                        matrix_qs=matrix_s0, &
    2544              :                                        almo_scf_env=almo_scf_env, &
    2545              :                                        name_new="K_BLK_1", &
    2546              :                                        size_keys=[almo_mat_dim_virt_disc, almo_mat_dim_virt], &
    2547              :                                        symmetry_new=dbcsr_type_no_symmetry, &
    2548              :                                        spin_key=ispin, &
    2549            0 :                                        init_domains=.TRUE.)
    2550              :                CALL matrix_almo_create(matrix_new=almo_scf_env%opt_k_denom(ispin), &
    2551              :                                        matrix_qs=matrix_s0, &
    2552              :                                        almo_scf_env=almo_scf_env, &
    2553              :                                        name_new="OPT_K_DENOM", &
    2554              :                                        size_keys=[almo_mat_dim_virt_disc, almo_mat_dim_virt], &
    2555              :                                        symmetry_new=dbcsr_type_no_symmetry, &
    2556              :                                        spin_key=ispin, &
    2557            0 :                                        init_domains=.FALSE.)
    2558              :                CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_k_tr(ispin), &
    2559              :                                        matrix_qs=matrix_s0, &
    2560              :                                        almo_scf_env=almo_scf_env, &
    2561              :                                        name_new="K_TR", &
    2562              :                                        size_keys=[almo_mat_dim_virt, almo_mat_dim_virt_disc], &
    2563              :                                        symmetry_new=dbcsr_type_no_symmetry, &
    2564              :                                        spin_key=ispin, &
    2565            0 :                                        init_domains=.FALSE.)
    2566              :                CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_v_disc_blk(ispin), &
    2567              :                                        matrix_qs=matrix_s0, &
    2568              :                                        almo_scf_env=almo_scf_env, &
    2569              :                                        name_new="V_DISC_BLK", &
    2570              :                                        size_keys=[almo_mat_dim_aobasis, almo_mat_dim_virt_disc], &
    2571              :                                        symmetry_new=dbcsr_type_no_symmetry, &
    2572              :                                        spin_key=ispin, &
    2573            0 :                                        init_domains=.FALSE.)
    2574              :                CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_v_disc(ispin), &
    2575              :                                        matrix_qs=matrix_s0, &
    2576              :                                        almo_scf_env=almo_scf_env, &
    2577              :                                        name_new="V_DISC", &
    2578              :                                        size_keys=[almo_mat_dim_aobasis, almo_mat_dim_virt_disc], &
    2579              :                                        symmetry_new=dbcsr_type_no_symmetry, &
    2580              :                                        spin_key=ispin, &
    2581            0 :                                        init_domains=.FALSE.)
    2582              :                CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_ov_disc(ispin), &
    2583              :                                        matrix_qs=matrix_s0, &
    2584              :                                        almo_scf_env=almo_scf_env, &
    2585              :                                        name_new="OV_DISC", &
    2586              :                                        size_keys=[almo_mat_dim_occ, almo_mat_dim_virt_disc], &
    2587              :                                        symmetry_new=dbcsr_type_no_symmetry, &
    2588              :                                        spin_key=ispin, &
    2589            0 :                                        init_domains=.FALSE.)
    2590              : 
    2591              :             END IF ! end need_discarded_virtuals
    2592              : 
    2593              :          END DO ! spin
    2594              :       END IF
    2595              : 
    2596              :       ! create matrices of orbital energies if necessary
    2597          122 :       IF (almo_scf_env%need_orbital_energies) THEN
    2598          372 :          ALLOCATE (almo_scf_env%matrix_eoo(nspins))
    2599          372 :          ALLOCATE (almo_scf_env%matrix_evv_full(nspins))
    2600          250 :          DO ispin = 1, nspins
    2601              :             CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_eoo(ispin), &
    2602              :                                     matrix_qs=matrix_s0, &
    2603              :                                     almo_scf_env=almo_scf_env, &
    2604              :                                     name_new="E_OCC", &
    2605              :                                     size_keys=[almo_mat_dim_occ, almo_mat_dim_occ], &
    2606              :                                     symmetry_new=dbcsr_type_no_symmetry, &
    2607              :                                     spin_key=ispin, &
    2608          128 :                                     init_domains=.FALSE.)
    2609              :             CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_evv_full(ispin), &
    2610              :                                     matrix_qs=matrix_s0, &
    2611              :                                     almo_scf_env=almo_scf_env, &
    2612              :                                     name_new="E_VIRT", &
    2613              :                                     size_keys=[almo_mat_dim_virt_full, almo_mat_dim_virt_full], &
    2614              :                                     symmetry_new=dbcsr_type_no_symmetry, &
    2615              :                                     spin_key=ispin, &
    2616          250 :                                     init_domains=.FALSE.)
    2617              :          END DO
    2618              :       END IF
    2619              : 
    2620              :       ! Density and KS matrices
    2621          372 :       ALLOCATE (almo_scf_env%matrix_p(nspins))
    2622          372 :       ALLOCATE (almo_scf_env%matrix_p_blk(nspins))
    2623          372 :       ALLOCATE (almo_scf_env%matrix_ks(nspins))
    2624          372 :       ALLOCATE (almo_scf_env%matrix_ks_blk(nspins))
    2625          122 :       IF (almo_scf_env%need_previous_ks) &
    2626          372 :          ALLOCATE (almo_scf_env%matrix_ks_0deloc(nspins))
    2627          250 :       DO ispin = 1, nspins
    2628              :          ! RZK-warning copy with symmery but remember that this might cause problems
    2629              :          CALL dbcsr_create(almo_scf_env%matrix_p(ispin), &
    2630              :                            template=almo_scf_env%matrix_s(1), &
    2631          128 :                            matrix_type=dbcsr_type_symmetric)
    2632              :          CALL dbcsr_create(almo_scf_env%matrix_ks(ispin), &
    2633              :                            template=almo_scf_env%matrix_s(1), &
    2634          128 :                            matrix_type=dbcsr_type_symmetric)
    2635          128 :          IF (almo_scf_env%need_previous_ks) THEN
    2636              :             CALL dbcsr_create(almo_scf_env%matrix_ks_0deloc(ispin), &
    2637              :                               template=almo_scf_env%matrix_s(1), &
    2638          128 :                               matrix_type=dbcsr_type_symmetric)
    2639              :          END IF
    2640              :          CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_p_blk(ispin), &
    2641              :                                  matrix_qs=matrix_s0, &
    2642              :                                  almo_scf_env=almo_scf_env, &
    2643              :                                  name_new="P_BLK", &
    2644              :                                  size_keys=[almo_mat_dim_aobasis, almo_mat_dim_aobasis], &
    2645              :                                  symmetry_new=dbcsr_type_symmetric, &
    2646              :                                  spin_key=ispin, &
    2647          128 :                                  init_domains=.TRUE.)
    2648              :          CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_ks_blk(ispin), &
    2649              :                                  matrix_qs=matrix_s0, &
    2650              :                                  almo_scf_env=almo_scf_env, &
    2651              :                                  name_new="KS_BLK", &
    2652              :                                  size_keys=[almo_mat_dim_aobasis, almo_mat_dim_aobasis], &
    2653              :                                  symmetry_new=dbcsr_type_symmetric, &
    2654              :                                  spin_key=ispin, &
    2655          250 :                                  init_domains=.TRUE.)
    2656              :       END DO
    2657              : 
    2658          122 :       CALL timestop(handle)
    2659              : 
    2660          122 :    END SUBROUTINE almo_scf_env_create_matrices
    2661              : 
    2662              : ! **************************************************************************************************
    2663              : !> \brief clean up procedures for almo scf
    2664              : !> \param almo_scf_env ...
    2665              : !> \par History
    2666              : !>       2011.06 created [Rustam Z Khaliullin]
    2667              : !>       2018.09 smearing support [Ruben Staub]
    2668              : !> \author Rustam Z Khaliullin
    2669              : ! **************************************************************************************************
    2670          122 :    SUBROUTINE almo_scf_clean_up(almo_scf_env)
    2671              : 
    2672              :       TYPE(almo_scf_env_type), INTENT(INOUT)             :: almo_scf_env
    2673              : 
    2674              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'almo_scf_clean_up'
    2675              : 
    2676              :       INTEGER                                            :: handle, ispin, unit_nr
    2677              :       TYPE(cp_logger_type), POINTER                      :: logger
    2678              : 
    2679          122 :       CALL timeset(routineN, handle)
    2680              : 
    2681              :       ! get a useful output_unit
    2682          122 :       logger => cp_get_default_logger()
    2683          122 :       IF (logger%para_env%is_source()) THEN
    2684           61 :          unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
    2685              :       ELSE
    2686              :          unit_nr = -1
    2687              :       END IF
    2688              : 
    2689              :       ! release matrices
    2690          122 :       CALL dbcsr_release(almo_scf_env%matrix_s(1))
    2691          122 :       CALL dbcsr_release(almo_scf_env%matrix_s_blk(1))
    2692          122 :       IF (almo_scf_env%almo_update_algorithm == almo_scf_diag) THEN
    2693           76 :          CALL dbcsr_release(almo_scf_env%matrix_s_blk_sqrt_inv(1))
    2694           76 :          CALL dbcsr_release(almo_scf_env%matrix_s_blk_sqrt(1))
    2695           46 :       ELSE IF (almo_scf_env%almo_update_algorithm == almo_scf_dm_sign) THEN
    2696            0 :          CALL dbcsr_release(almo_scf_env%matrix_s_blk_inv(1))
    2697              :       END IF
    2698          250 :       DO ispin = 1, almo_scf_env%nspins
    2699          128 :          CALL dbcsr_release(almo_scf_env%quench_t(ispin))
    2700          128 :          CALL dbcsr_release(almo_scf_env%quench_t_blk(ispin))
    2701          128 :          CALL dbcsr_release(almo_scf_env%matrix_t_blk(ispin))
    2702          128 :          CALL dbcsr_release(almo_scf_env%matrix_err_blk(ispin))
    2703          128 :          CALL dbcsr_release(almo_scf_env%matrix_err_xx(ispin))
    2704          128 :          CALL dbcsr_release(almo_scf_env%matrix_t_tr(ispin))
    2705          128 :          CALL dbcsr_release(almo_scf_env%matrix_sigma(ispin))
    2706          128 :          CALL dbcsr_release(almo_scf_env%matrix_sigma_blk(ispin))
    2707          128 :          CALL dbcsr_release(almo_scf_env%matrix_sigma_inv_0deloc(ispin))
    2708          128 :          CALL dbcsr_release(almo_scf_env%matrix_sigma_inv(ispin))
    2709          128 :          CALL dbcsr_release(almo_scf_env%matrix_t(ispin))
    2710          128 :          CALL dbcsr_release(almo_scf_env%matrix_sigma_sqrt(ispin))
    2711          128 :          CALL dbcsr_release(almo_scf_env%matrix_sigma_sqrt_inv(ispin))
    2712          128 :          CALL dbcsr_release(almo_scf_env%matrix_p(ispin))
    2713          128 :          CALL dbcsr_release(almo_scf_env%matrix_ks(ispin))
    2714          128 :          CALL dbcsr_release(almo_scf_env%matrix_p_blk(ispin))
    2715          128 :          CALL dbcsr_release(almo_scf_env%matrix_ks_blk(ispin))
    2716          128 :          IF (almo_scf_env%need_previous_ks) THEN
    2717          128 :             CALL dbcsr_release(almo_scf_env%matrix_ks_0deloc(ispin))
    2718              :          END IF
    2719          128 :          IF (almo_scf_env%need_virtuals) THEN
    2720          128 :             CALL dbcsr_release(almo_scf_env%matrix_v_blk(ispin))
    2721          128 :             CALL dbcsr_release(almo_scf_env%matrix_v_full_blk(ispin))
    2722          128 :             CALL dbcsr_release(almo_scf_env%matrix_v(ispin))
    2723          128 :             CALL dbcsr_release(almo_scf_env%matrix_vo(ispin))
    2724          128 :             CALL dbcsr_release(almo_scf_env%matrix_x(ispin))
    2725          128 :             CALL dbcsr_release(almo_scf_env%matrix_ov(ispin))
    2726          128 :             CALL dbcsr_release(almo_scf_env%matrix_ov_full(ispin))
    2727          128 :             CALL dbcsr_release(almo_scf_env%matrix_sigma_vv(ispin))
    2728          128 :             CALL dbcsr_release(almo_scf_env%matrix_sigma_vv_blk(ispin))
    2729          128 :             CALL dbcsr_release(almo_scf_env%matrix_sigma_vv_sqrt(ispin))
    2730          128 :             CALL dbcsr_release(almo_scf_env%matrix_sigma_vv_sqrt_inv(ispin))
    2731          128 :             CALL dbcsr_release(almo_scf_env%matrix_vv_full_blk(ispin))
    2732          128 :             IF (almo_scf_env%deloc_truncate_virt /= virt_full) THEN
    2733            0 :                CALL dbcsr_release(almo_scf_env%matrix_k_tr(ispin))
    2734            0 :                CALL dbcsr_release(almo_scf_env%matrix_k_blk(ispin))
    2735            0 :                CALL dbcsr_release(almo_scf_env%matrix_k_blk_ones(ispin))
    2736            0 :                CALL dbcsr_release(almo_scf_env%matrix_v_disc(ispin))
    2737            0 :                CALL dbcsr_release(almo_scf_env%matrix_v_disc_blk(ispin))
    2738            0 :                CALL dbcsr_release(almo_scf_env%matrix_ov_disc(ispin))
    2739            0 :                CALL dbcsr_release(almo_scf_env%matrix_vv_disc_blk(ispin))
    2740            0 :                CALL dbcsr_release(almo_scf_env%matrix_vv_disc(ispin))
    2741            0 :                CALL dbcsr_release(almo_scf_env%opt_k_t_dd(ispin))
    2742            0 :                CALL dbcsr_release(almo_scf_env%opt_k_t_rr(ispin))
    2743            0 :                CALL dbcsr_release(almo_scf_env%opt_k_denom(ispin))
    2744              :             END IF
    2745              :          END IF
    2746          250 :          IF (almo_scf_env%need_orbital_energies) THEN
    2747          128 :             CALL dbcsr_release(almo_scf_env%matrix_eoo(ispin))
    2748          128 :             CALL dbcsr_release(almo_scf_env%matrix_evv_full(ispin))
    2749              :          END IF
    2750              :       END DO
    2751              : 
    2752              :       ! deallocate matrices
    2753          122 :       DEALLOCATE (almo_scf_env%matrix_p)
    2754          122 :       DEALLOCATE (almo_scf_env%matrix_p_blk)
    2755          122 :       DEALLOCATE (almo_scf_env%matrix_ks)
    2756          122 :       DEALLOCATE (almo_scf_env%matrix_ks_blk)
    2757          122 :       DEALLOCATE (almo_scf_env%matrix_t_blk)
    2758          122 :       DEALLOCATE (almo_scf_env%matrix_err_blk)
    2759          122 :       DEALLOCATE (almo_scf_env%matrix_err_xx)
    2760          122 :       DEALLOCATE (almo_scf_env%matrix_t)
    2761          122 :       DEALLOCATE (almo_scf_env%matrix_t_tr)
    2762          122 :       DEALLOCATE (almo_scf_env%matrix_sigma)
    2763          122 :       DEALLOCATE (almo_scf_env%matrix_sigma_blk)
    2764          122 :       DEALLOCATE (almo_scf_env%matrix_sigma_inv_0deloc)
    2765          122 :       DEALLOCATE (almo_scf_env%matrix_sigma_sqrt)
    2766          122 :       DEALLOCATE (almo_scf_env%matrix_sigma_sqrt_inv)
    2767          122 :       DEALLOCATE (almo_scf_env%matrix_sigma_inv)
    2768          122 :       DEALLOCATE (almo_scf_env%quench_t)
    2769          122 :       DEALLOCATE (almo_scf_env%quench_t_blk)
    2770          122 :       IF (almo_scf_env%need_virtuals) THEN
    2771          122 :          DEALLOCATE (almo_scf_env%matrix_v_blk)
    2772          122 :          DEALLOCATE (almo_scf_env%matrix_v_full_blk)
    2773          122 :          DEALLOCATE (almo_scf_env%matrix_v)
    2774          122 :          DEALLOCATE (almo_scf_env%matrix_vo)
    2775          122 :          DEALLOCATE (almo_scf_env%matrix_x)
    2776          122 :          DEALLOCATE (almo_scf_env%matrix_ov)
    2777          122 :          DEALLOCATE (almo_scf_env%matrix_ov_full)
    2778          122 :          DEALLOCATE (almo_scf_env%matrix_sigma_vv)
    2779          122 :          DEALLOCATE (almo_scf_env%matrix_sigma_vv_blk)
    2780          122 :          DEALLOCATE (almo_scf_env%matrix_sigma_vv_sqrt)
    2781          122 :          DEALLOCATE (almo_scf_env%matrix_sigma_vv_sqrt_inv)
    2782          122 :          DEALLOCATE (almo_scf_env%matrix_vv_full_blk)
    2783          122 :          IF (almo_scf_env%deloc_truncate_virt /= virt_full) THEN
    2784            0 :             DEALLOCATE (almo_scf_env%matrix_k_tr)
    2785            0 :             DEALLOCATE (almo_scf_env%matrix_k_blk)
    2786            0 :             DEALLOCATE (almo_scf_env%matrix_v_disc)
    2787            0 :             DEALLOCATE (almo_scf_env%matrix_v_disc_blk)
    2788            0 :             DEALLOCATE (almo_scf_env%matrix_ov_disc)
    2789            0 :             DEALLOCATE (almo_scf_env%matrix_vv_disc_blk)
    2790            0 :             DEALLOCATE (almo_scf_env%matrix_vv_disc)
    2791            0 :             DEALLOCATE (almo_scf_env%matrix_k_blk_ones)
    2792            0 :             DEALLOCATE (almo_scf_env%opt_k_t_dd)
    2793            0 :             DEALLOCATE (almo_scf_env%opt_k_t_rr)
    2794            0 :             DEALLOCATE (almo_scf_env%opt_k_denom)
    2795              :          END IF
    2796              :       END IF
    2797          122 :       IF (almo_scf_env%need_previous_ks) THEN
    2798          122 :          DEALLOCATE (almo_scf_env%matrix_ks_0deloc)
    2799              :       END IF
    2800          122 :       IF (almo_scf_env%need_orbital_energies) THEN
    2801          122 :          DEALLOCATE (almo_scf_env%matrix_eoo)
    2802          122 :          DEALLOCATE (almo_scf_env%matrix_evv_full)
    2803              :       END IF
    2804              : 
    2805              :       ! clean up other variables
    2806          250 :       DO ispin = 1, almo_scf_env%nspins
    2807              :          CALL release_submatrices( &
    2808          128 :             almo_scf_env%domain_preconditioner(:, ispin))
    2809          128 :          CALL release_submatrices(almo_scf_env%domain_s_inv(:, ispin))
    2810          128 :          CALL release_submatrices(almo_scf_env%domain_s_sqrt_inv(:, ispin))
    2811          128 :          CALL release_submatrices(almo_scf_env%domain_s_sqrt(:, ispin))
    2812          128 :          CALL release_submatrices(almo_scf_env%domain_ks_xx(:, ispin))
    2813          128 :          CALL release_submatrices(almo_scf_env%domain_t(:, ispin))
    2814          128 :          CALL release_submatrices(almo_scf_env%domain_err(:, ispin))
    2815          250 :          CALL release_submatrices(almo_scf_env%domain_r_down_up(:, ispin))
    2816              :       END DO
    2817          956 :       DEALLOCATE (almo_scf_env%domain_preconditioner)
    2818          956 :       DEALLOCATE (almo_scf_env%domain_s_inv)
    2819          956 :       DEALLOCATE (almo_scf_env%domain_s_sqrt_inv)
    2820          956 :       DEALLOCATE (almo_scf_env%domain_s_sqrt)
    2821          956 :       DEALLOCATE (almo_scf_env%domain_ks_xx)
    2822          956 :       DEALLOCATE (almo_scf_env%domain_t)
    2823          956 :       DEALLOCATE (almo_scf_env%domain_err)
    2824          956 :       DEALLOCATE (almo_scf_env%domain_r_down_up)
    2825          250 :       DO ispin = 1, almo_scf_env%nspins
    2826          128 :          DEALLOCATE (almo_scf_env%domain_map(ispin)%pairs)
    2827          250 :          DEALLOCATE (almo_scf_env%domain_map(ispin)%index1)
    2828              :       END DO
    2829          250 :       DEALLOCATE (almo_scf_env%domain_map)
    2830          122 :       DEALLOCATE (almo_scf_env%domain_index_of_ao)
    2831          122 :       DEALLOCATE (almo_scf_env%domain_index_of_atom)
    2832          122 :       DEALLOCATE (almo_scf_env%first_atom_of_domain)
    2833          122 :       DEALLOCATE (almo_scf_env%last_atom_of_domain)
    2834          122 :       DEALLOCATE (almo_scf_env%nbasis_of_domain)
    2835          122 :       IF (ALLOCATED(almo_scf_env%nocc_of_domain)) THEN
    2836          122 :          DEALLOCATE (almo_scf_env%nocc_of_domain)
    2837              :       END IF
    2838          122 :       DEALLOCATE (almo_scf_env%real_ne_of_domain)
    2839          122 :       DEALLOCATE (almo_scf_env%nvirt_full_of_domain)
    2840          122 :       DEALLOCATE (almo_scf_env%nvirt_of_domain)
    2841          122 :       DEALLOCATE (almo_scf_env%nvirt_disc_of_domain)
    2842          122 :       DEALLOCATE (almo_scf_env%mu_of_domain)
    2843          122 :       DEALLOCATE (almo_scf_env%cpu_of_domain)
    2844          122 :       DEALLOCATE (almo_scf_env%charge_of_domain)
    2845          122 :       DEALLOCATE (almo_scf_env%multiplicity_of_domain)
    2846          122 :       DEALLOCATE (almo_scf_env%activate)
    2847          122 :       IF (almo_scf_env%smear) THEN
    2848            4 :          DEALLOCATE (almo_scf_env%mo_energies)
    2849            4 :          DEALLOCATE (almo_scf_env%kTS)
    2850              :       END IF
    2851              : 
    2852          122 :       DEALLOCATE (almo_scf_env%domain_index_of_ao_block)
    2853          122 :       DEALLOCATE (almo_scf_env%domain_index_of_mo_block)
    2854              : 
    2855          122 :       CALL mp_para_env_release(almo_scf_env%para_env)
    2856          122 :       CALL cp_blacs_env_release(almo_scf_env%blacs_env)
    2857              : 
    2858          122 :       CALL timestop(handle)
    2859              : 
    2860          122 :    END SUBROUTINE almo_scf_clean_up
    2861              : 
    2862              : ! **************************************************************************************************
    2863              : !> \brief Do post scf calculations with ALMO
    2864              : !>        WARNING: ALMO post scf calculation may not work for certain quantities,
    2865              : !>        like forces, since ALMO wave function is only 'partially' optimized
    2866              : !> \param qs_env ...
    2867              : !> \par History
    2868              : !>       2016.12 created [Yifei Shi]
    2869              : !> \author Yifei Shi
    2870              : ! **************************************************************************************************
    2871          122 :    SUBROUTINE almo_post_scf_compute_properties(qs_env)
    2872              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    2873              : 
    2874          122 :       CALL qs_scf_compute_properties(qs_env)
    2875              : 
    2876          122 :    END SUBROUTINE almo_post_scf_compute_properties
    2877              : 
    2878              : END MODULE almo_scf
    2879              : 
        

Generated by: LCOV version 2.0-1